2017-01-13 3 views
2

Мне нужно написать запрос, который ниже. Я пытался, но не мог писать. Пожалуйста, помогите мне.Нужна помощь при написании SQL-запроса с динамическими столбцами

У меня есть таблица, которая возвращается ниже результата набора.

select * 
from table1; --(rowid and ColumnName are columns of the table) 

Выход:

rowid  ColumnName 
------------------------------ 
    1  Segment1  
    2  Segment2 

У меня есть другая таблица, которая имеет ниже структуру: (Segment1 и Segment2 столбцы здесь)

select * 
from table2; 

Выход:

appId  Segment1  Segment2  Segment3 
--------------------------------------------- 
    a1  fld1   fld2   per 
    a2  cmp1   hcd4   klp 

I нужно написать запрос, h считывает значения «ColumnName» из первой таблицы и извлекает значения столбцов во второй таблице.

Это означает, что из таблицы 1 я буду знать, какие доступные столбцы я столбец2 и из таблицы2, я буду знать, какие данные хранятся в этих столбцах.

Пожалуйста, дайте мне знать, если я не понимаю. Этот запрос находится в Oracle SQL

+0

Каков запрос к первой таблице .. i.e на каком основании вы выбираете, если вывод из таблицы 1 является сегментом1 или сегментом2? –

+0

Мне нужно прочитать все значения столбца ColumnName в таблице1 и получить их значения из таблицы2. – Anveshan

+0

Значения из столбца «Имя столбца» из таблицы 1 должны отображаться с именами столбцов в таблице 2 и должны возвращать значения – Anveshan

ответ

1

Как уже упоминалось в комментарии вам нужен PLSQL блок с динамическим SQL , Ниже пример:

Таблицы:

create table table1 (row_id number, 
        ColumnName varchar2(100)) 

create table table2 (appId  number, 
        Segment1 varchar2(100), 
        Segment2 varchar2(100),  
        Segment3 varchar2(100)); 

Insert all 
    into TABLE1 (ROW_ID, COLUMNNAME) Values (1, 'Segment1') 
    into TABLE1 (ROW_ID, COLUMNNAME) Values (2, 'Segment2') 
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3) Values (1, 'RRR', 'KKK', 'MMM') 
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3) Values (2, 'ZZZ', 'PPP', 'QQQ') 
    into TABLE2 (APPID, SEGMENT1, SEGMENT2, SEGMENT3) Values (3, 'LLL', 'NNN', 'DDD') 
select * from dual; 

Код:

DECLARE 
    var  VARCHAR2 (1000); 
    v_sql VARCHAR2 (2000); 
    TYPE x_var IS TABLE OF VARCHAR2(1000); 
    z_var x_var; 
    num number:=0; 
BEGIN 
    FOR rec IN ( SELECT DISTINCT columnname 
        FROM table1 
        ORDER BY 1) 
    LOOP   
     num := num +1;  
     if num = 1 then 
     var:= rec.columnname;  
     else 
     var := var || ' || '' , ''||' || rec.columnname; 
     end if; 

    END LOOP; 

    var := RTRIM (LTRIM (var, ','), ','); 

    v_sql := 'select '|| var ||' from table2';  

    EXECUTE IMMEDIATE v_sql BULK COLLECT INTO z_var; 

    FOR i IN 1 .. z_var.COUNT 
    LOOP 
     DBMS_OUTPUT.put_line (z_var(i)); 
    END LOOP; 
END; 

Выход:

SQL>/
RRR , KKK 
ZZZ , PPP 
LLL , NNN 
0

Будет ли приведенный ниже блок PL PL PLUS выполнять ваши требования.

BEGIN 
FOR iter IN (
       SELECT column_name 
       FROM all_tab_columns 
       WHERE upper(table_name) = 'table1' 
       AND UPPER(column_name) LIKE 'SEGMENT%' 
      )  
     LOOP 
      SELECT iter.column_name INTO temp_table FROM table1 
      dbms_output.put_line(temp_table.column_name); 
     END LOOP; 
END; 
/
+0

Небольшое описание в вашем ответе, в котором рассказывается о том, как SQL, который вы предоставили, будет отлично. – Tom

+0

Это не работает; Ты это пробовал? – Aleksej

0

Скажем, у вас есть таблицы, как следующее:

SQL> select * from someTable; 

    COLUMN1 COLUMN2 COLUMN3 
---------- ---------- ---------- 
     1   2   3 
     2   4   6 
     3   6   9 

SQL> select * from tableOfColumns; 

COLUMNN 
------- 
column1 
column3 

Вам может понадобиться что-то вроде следующего:

SQL> declare 
    2  type tListOfResults is table of varchar2(1000); 
    3  vSQL varchar2(1000); 
    4  vResult tListOfResults ; 
    5 begin 
    6  select 'select ' || listagg (columnName, ' || '', '' || ') within group (order by columnName) || ' from someTable' 
    7  into vSQL 
    8  from tableOfColumns; 
    9  -- 
10  execute immediate vSQL bulk collect into vResult; 
11  if vResult.count() > 0 then 
12   for i in vResult.first .. vResult.last loop 
13    dbms_output.put_line(vResult(i)); 
14   end loop; 
15  end if; 
16 end; 
17/
1, 3 
2, 6 
3, 9 

PL/SQL procedure successfully completed. 
+0

Я вижу синтаксическую ошибку в приведенном выше скрипте. «Частично признанные правила (железнодорожные диаграммы): .. – Anveshan

+0

Эта ошибка, похоже, не имеет ничего общего с кодом Oracle, как вы ее запустили? Объявление, что является полным сообщением об ошибке? – Aleksej

1

Динамические столбцы в SQL заявления почти всегда плохая идея. Обычно есть возможность избежать подобных проблем и создать более простое решение.

Но если это один из тех редких случаев, когда вы действительно нужно запускать динамический SQL в SQL, то вам необходимо установить и запустить что-то вроде моего открытого исходного проекта Method4.

Например:

create table table1 as 
select 1 id, 'Segment1' columnName from dual union all 
select 2 id, 'Segment2' columnName from dual; 

create table table2 as 
select 'a1' appId, 'fld1' Segment1, 'fld2' Segment2, 'per' Segment3 from dual union all 
select 'a2' appId, 'cmp1' Segment1, 'hcd4' Segment2, 'klp' Segment3 from dual; 

select * from table(method4.dynamic_query(
    q'[ 
     select 
       'select appID, ' 
      ||listagg(columnName, ',') within group (order by id) 
      ||' from table2' 
      sql_statement 
     from table1 
    ]' 
)); 

APPID SEGMENT1 SEGMENT2 
----- -------- -------- 
a1  fld1  fld2 
a2  cmp1  hcd4 

Есть много недостатков, чтобы продолжить этот путь. Код сложный, медленный и имеет нечетное поведение. Для объяснения того, как это работает, см. this article от Adrian Billington.

Смежные вопросы