2016-04-01 6 views
0

У меня есть таблица, которая содержит список динамических представлений SQL, который должен быть созданDynamic SQL таблицы с использованием конфигурации

SEEDING_TABLE 
------------- 
KEYVALUE|VIEW_TO_BE_CREATED|FROMTABLE|NOOFCOLS 
1|A|A1|3 
2|B|B1|4 
3|C|C1|5 

Другая таблица, которая содержит фактические имена столбцов для приведенной выше таблицы высева

ORDERCOLS_FORVIEW 
KEYVALUE|FROMTABLE|COLSAVAILABLE 
1|A1|NUM1 
1|A1|NUM2 
1|A1|NUM3 
2|B1|NUM1 
2|B1|NUM2 
2|B1|NUM3 
2|B1|NUM4 
3|C1|NUM1 
3|C1|NUM2 
3|C1|NUM3 
3|C1|NUM4 
3|C1|NUM5 

Определение таблицы FROMTABLEs следующим

A1 -> KEYVALUE|NUM1|NUM2|NUM3 
B1 -> KEYVALUE|NUM1|NUM2|NUM3|NUM4 
C1 -> KEYVALUE|NUM1|NUM2|NUM3|NUM4|NUM5 

После этого всю нашу логику и магнум IC результат должен быть динамическим SQL, который должен произвести следующие заявления вида

DYNAMIC_ENTRIES -> TEXT|TABLE|RANK 
TEXT              |TABLE | RANK 
CREATE OR REPLACE VIEW A AS SELECT       | A | 1 
KEYVALUE,             | A | 2 
NUM1 AS KEY1,            | A | 3 
NUM1 AS NO1,            | A | 4 
NUM1||'|'||NUM2 AS KEY2,         | A | 5 
NUM2 AS NO2,            | A | 6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,      | A | 7 
NUM3 AS NO3            | A | 8 
FROM A1;             | A | 9 
CREATE OR REPLACE VIEW B AS SELECT       | B | 1 
KEYVALUE,             | B | 2 
NUM1 AS KEY1,            | B | 3 
NUM1 AS NO1,            | B | 4 
NUM1||'|'||NUM2 AS KEY2,         | B | 5 
NUM2 AS NO2,            | B | 6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,      | B | 7 
NUM3 AS NO3,            | B | 8 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4 AS KEY4,    | B | 9 
NUM4 AS NO4            | B | 10 
FROM B1;             | B | 11 
CREATE OR REPLACE VIEW C AS SELECT       | C | 1 
KEYVALUE,             | C | 2 
NUM1 AS KEY1,            | C | 3 
NUM1 AS NO1,            | C | 4 
NUM1||'|'||NUM2 AS KEY2,         | C | 5 
NUM2 AS NO2,            | C | 6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,      | C | 7 
NUM3 AS NO3,            | C | 8 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4 AS KEY4,    | C | 9 
NUM4 AS NO4            | C | 10 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4||'|'||NUM5 AS KEY5, | C | 11 
NUM5 AS NO5            | C | 12 
FROM C1;             | C | 13 

Если предположить для каждой записи в таблице высева, у нас есть полный список столбцов, доступных в поиске. Логика заключается в том, что для каждой записи в таблице посева нам нужно вставить записи в итоговую динамическую таблицу SQL для создания представлений для записей в столбце VIEW_TO_BE_CREATED с помощью FROMTABLE. Для каждого столбца в FROMTABLE, который имеет последовательность, такую ​​как NUM1 ... NUMn, они должны быть объединены как дерево.

Я смущен о том, как подойти к этому. Для этого мы можем создать любое количество промежуточных таблиц или представлений. Любые указатели на это были бы высоко оценены?

+1

В чем Ваш вопрос? – CathalMF

+0

регулярно ли обновляется эта информация? т.е. это пакетная работа ETL? принести его, трансформировать и сделать доступным через представление? – kevinsky

+0

Может меняться один раз в месяц, а таблицы конфигурации обрабатываются вручную. – SriniV

ответ

1

Это немного грязное, но вы можете сделать это в простом SQL, начиная с иерархическим запросом, чтобы получить сцепленные строки:

select keyvalue, fromtable, colsavailable, rnk, 
    ltrim(sys_connect_by_path(colsavailable, '||''|''||'), '||''|''||') as path 
from ordercols_forview 
start with rnk = 1 
connect by keyvalue = prior keyvalue 
and rnk = prior rnk + 1 
and prior dbms_random.value is not null 
order by keyvalue, fromtable, colsavailable, rnk; 

    KEYVALUE FR COLS  RNK PATH            
---------- -- ---- ---------- -------------------------------------------------- 
     1 A1 NUM1   1 NUM1            
     1 A1 NUM2   2 NUM1||'|'||NUM2         
     1 A1 NUM3   3 NUM1||'|'||NUM2||'|'||NUM3       
     2 B1 NUM1   1 NUM1            
     2 B1 NUM2   2 NUM1||'|'||NUM2         
     2 B1 NUM3   3 NUM1||'|'||NUM2||'|'||NUM3       
     2 B1 NUM4   4 NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4    
     3 C1 NUM1   1 NUM1            
     3 C1 NUM2   2 NUM1||'|'||NUM2         
     3 C1 NUM3   3 NUM1||'|'||NUM2||'|'||NUM3       
     3 C1 NUM4   4 NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4    
     3 C1 NUM5   5 NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4||'|'||NUM5 

Я предполагал, что ваша таблица действительно имеет еще один столбец, у вас есть не показано, что дает положение столбца. Если нет, вы можете создать это как-то - возможно, на основе column_id для столбца базовой таблицы, в алфавитном порядке или любого другого. Вам просто нужна последовательность смежных чисел для предложения connect-by.

Затем вы можете использовать два союза для получения текстовых частей для этих значений столбца и пути (так как они должны быть отдельными строками в финальной таблице), плюс дополнительные для линий SELECT ... и FROM .... Каждому из них требуется другое сгенерированное число ранга. Таковыми могут быть получены из рейтинга в КТР:

with ordercols_forview_cte as (
    select keyvalue, fromtable, colsavailable, rnk, 
    ltrim(sys_connect_by_path(colsavailable, '||''|''||'), '||''|''||') as path 
    from ordercols_forview 
    start with rnk = 1 
    connect by keyvalue = prior keyvalue 
    and rnk = prior rnk + 1 
    and prior dbms_random.value is not null 
) 
select 'CREATE OR REPLACE VIEW ' || s.view_to_be_created || ' AS SELECT ' as text, 
    s.view_to_be_created, 1 as rnk 
from seeding_table s 
union all 
select 'KEYVALUE,' as text, 
    s.view_to_be_created, 2 as rnk 
from seeding_table s 
union all 
select o.path || ' AS KEY' || o.rnk 
    || case when o.rnk < s.noofcols then ',' end, 
    s.view_to_be_created, (o.rnk * 2) + 1 as rnk 
from seeding_table s 
join ordercols_forview_cte o on o.keyvalue = s.keyvalue 
union all 
select o.colsavailable || ' AS NO' || o.rnk 
    || case when o.rnk < s.noofcols then ',' end as text, 
    s.view_to_be_created, (o.rnk * 2) + 2 as rnk 
from seeding_table s 
join ordercols_forview_cte o on o.keyvalue = s.keyvalue 
union all 
select 'FROM ' || o.fromtable || ';' as text, 
    s.view_to_be_created, (s.noofcols * 2) + 3 as rnk 
from seeding_table s 
join ordercols_forview_cte o on o.keyvalue = s.keyvalue 
where o.rnk = s.noofcols 
order by view_to_be_created, rnk; 

Что с исходными данными генерирует:

TEXT               V  RNK 
------------------------------------------------------------ - ---------- 
CREATE OR REPLACE VIEW A AS SELECT       A   1 
KEYVALUE,             A   2 
NUM1 AS KEY1,            A   3 
NUM1 AS NO1,             A   4 
NUM1||'|'||NUM2 AS KEY2,          A   5 
NUM2 AS NO2,             A   6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3       A   7 
NUM3 AS NO3             A   8 
FROM A1;              A   9 
CREATE OR REPLACE VIEW B AS SELECT       B   1 
KEYVALUE,             B   2 
NUM1 AS KEY1,            B   3 
NUM1 AS NO1,             B   4 
NUM1||'|'||NUM2 AS KEY2,          B   5 
NUM2 AS NO2,             B   6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,       B   7 
NUM3 AS NO3,             B   8 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4 AS KEY4    B   9 
NUM4 AS NO4             B   10 
FROM B1;              B   11 
CREATE OR REPLACE VIEW C AS SELECT       C   1 
KEYVALUE,             C   2 
NUM1 AS KEY1,            C   3 
NUM1 AS NO1,             C   4 
NUM1||'|'||NUM2 AS KEY2,          C   5 
NUM2 AS NO2,             C   6 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,       C   7 
NUM3 AS NO3,             C   8 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4 AS KEY4,    C   9 
NUM4 AS NO4,             C   10 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4||'|'||NUM5 AS KEY5  C   11 
NUM5 AS NO5             C   12 
FROM C1;              C   13 

Вы можете изменить его немного, имея другой КТР с соединения между seeding_table и ordercols_forview_cte и используя это для объединения. Вы также можете получить пути из рекурсивного CTE (с Oracle 11g):

with r (keyvalue, fromtable, colsavailable, rnk, path) as (
    select keyvalue, fromtable, colsavailable, rnk, colsavailable 
    from ordercols_forview 
    where rnk = 1 
    union all 
    select ocfv.keyvalue, ocfv.fromtable, ocfv.colsavailable, ocfv.rnk, 
    r.path || q'[||'|'||]' || ocfv.colsavailable 
    from r 
    join ordercols_forview ocfv 
    on ocfv.keyvalue = r.keyvalue 
    and ocfv.fromtable = r.fromtable 
    and ocfv.rnk = r.rnk + 1 
) 
select * from r; 

И затем можно использовать, что вместо; это соединение между этим рекурсивным КТРОМ и таблицей высева в другом КТРЕ, как упоминалось выше, но вы coudl просто заменить КТР иерархического-запрос с рекурсивным:

with r (keyvalue, fromtable, colsavailable, rnk, path) as (
    select keyvalue, fromtable, colsavailable, rnk, colsavailable 
    from ordercols_forview 
    where rnk = 1 
    union all 
    select ocfv.keyvalue, ocfv.fromtable, ocfv.colsavailable, ocfv.rnk, 
    r.path || q'[||'|'||]' || ocfv.colsavailable 
    from r 
    join ordercols_forview ocfv 
    on ocfv.keyvalue = r.keyvalue 
    and ocfv.fromtable = r.fromtable 
    and ocfv.rnk = r.rnk + 1 
), 
combined_cte as (
    select s.keyvalue, s.view_to_be_created, s.noofcols, 
    r.fromtable, r.colsavailable, r.rnk, r.path 
    from seeding_table s 
    join r on r.keyvalue = s.keyvalue 
) 
select 'CREATE OR REPLACE VIEW ' || c.view_to_be_created || ' AS SELECT ' as text, 
    c.view_to_be_created, c.rnk 
from combined_cte c 
where c.rnk = 1 
union all 
select 'KEYVALUE,' as text, 
    c.view_to_be_created, c.rnk + 1 as rnk 
from combined_cte c 
where c.rnk = 1 
union all 
select c.path || ' AS KEY' || c.rnk 
    || case when c.rnk < c.noofcols then ',' end, 
    c.view_to_be_created, (c.rnk * 2) + 1 as rnk 
from combined_cte c 
union all 
select c.colsavailable || ' AS NO' || c.rnk 
    || case when c.rnk < c.noofcols then ',' end as text, 
    c.view_to_be_created, (c.rnk * 2) + 2 as rnk 
from combined_cte c 
union all 
select 'FROM ' || c.fromtable || ';' as text, 
    c.view_to_be_created, (c.noofcols * 2) + 3 as rnk 
from combined_cte c 
where c.rnk = c.noofcols 
order by view_to_be_created, rnk; 

который получает тот же результат:

TEXT               V  RNK 
------------------------------------------------------------ - ---------- 
CREATE OR REPLACE VIEW A AS SELECT       A   1 
KEYVALUE,             A   2 
NUM1 AS KEY1,            A   3 
NUM1 AS NO1,             A   4 
NUM1||'|'||NUM2 AS KEY2,          A   5 
NUM2 AS NO2,             A   6 
... 
NUM1||'|'||NUM2||'|'||NUM3 AS KEY3,       C   7 
NUM3 AS NO3,             C   8 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4 AS KEY4,    C   9 
NUM4 AS NO4,             C   10 
NUM1||'|'||NUM2||'|'||NUM3||'|'||NUM4||'|'||NUM5 AS KEY5  C   11 
NUM5 AS NO5             C   12 
FROM C1;              C   13 
+0

У Alex есть способ сделать это, используя синтаксис ANSI Sql, а не синтаксис иерархического запроса оракула, – SriniV

+0

@realspirituals - уверен, используя Oracle 11g или выше, вы можете использовать рекурсивный CTE вместо иерархического запроса. Надеюсь, это то, что вы имеете в виду! Я добавил версию, которая использует это для моего ответа. –

+0

Отличный ответ помощник. Это дало мне хорошую отправную точку, чтобы вникать. – SriniV