2016-04-01 15 views
0

Ich habe eine Tabelle, die eine Liste von dynamischen SQL-Ansichten enthält, dieDynamische SQL mit Konfigurationstabellen

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

Die andere Tabelle, die enthält die eigentlichen Spaltennamen für die oben Seeding-Tabelle erstellt werden muss

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 

Definition der Tabelle FROMTABLEs als Nach all unsere Logik und mag

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

folgt ic das Ergebnis eine dynamische SQL sein sollte, die in der Seeding-Tabelle für jeden Eintrag

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 

Unter der Annahme, die unten Ansicht Aussagen produzieren sollten, haben wir die komplette Liste der Spalten in dem Look-up zur Verfügung. Die Logik besteht darin, dass wir für jeden Eintrag in der Seeding-Tabelle Einträge in die endgültige dynamische SQL-Tabelle einfügen müssen, um mithilfe der FROMTABLE Ansichten für die Einträge in der Spalte VIEW_TO_BE_CREATED zu erstellen. Für jede Spalte in der FROMTABLE mit der Sequenz NUM1 ... NUMn müssen sie wie ein Baum verkettet werden.

Ich bin verwirrt auf, wie man sich nähert. Wir können eine beliebige Anzahl von Zwischentabellen oder Sichten erstellen, um dies zu erreichen. Irgendwelche Hinweise dafür würden sehr geschätzt werden?

+1

Was ist Ihre Frage? – CathalMF

+0

werden diese Daten regelmäßig aktualisiert? dh ist das ein Batch-ETL-Job? einbringen, transformieren und durch einen Blick zugänglich machen? – kevinsky

+0

Kann einmal im Monat geändert werden und die Config-Tabellen werden manuell gepflegt – SriniV

Antwort

1

Es ist ein bisschen chaotisch, aber Sie es in Ebene SQL tun konnte, mit einer hierarchischen Abfrage starten die verketteten Strings zu erhalten:

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 

ich Ihren Tisch angenommen habe wirklich eine andere Spalte hat man nicht haben gezeigt, dass die Spalte Position gibt. Wenn nicht, können Sie das irgendwie erzeugen - vielleicht basierend auf column_id für die Basistabelle, alphabetisch oder was auch immer. Sie benötigen nur eine zusammenhängende Zahlenfolge für die Connect-By-Klausel.

Sie können dann zwei Gewerkschaften verwenden, um die Textteile für diese Spalte und Pfadwerte zu bekommen, plus extra diejenigen für die SELECT ... und FROM ... Linien (da sie getrennte Zeilen in Ihrem Final Table sein müssen). Jeder von diesen benötigt eine andere generierte Rangnummer. Diese können von der Platzierung in der CTE generiert werden:

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; 

, die mit Ihrem Ausgangsdaten erzeugt:

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 

Sie es ein bisschen variieren könnte, einen anderen CTE mit der Verbindung zwischen seeding_table und ordercols_forview_cte und Verwenden Sie das für die Vereinigung. Sie können auch die Pfade von einem rekursiven CTE (von Oracle 11g) erhalten:

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; 

Und kann dann das stattdessen verwenden; dies ist die zwischen dem rekursiven CTE und dem Säen Tabelle in einem anderen CTE zu verbinden, wie oben erwähnt, aber Sie coudl die hierarchische-Abfrage CTE mit den rekursiven eines gerade ersetzen:

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; 

das das gleiche Ergebnis erhält:

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 ist eine Möglichkeit, die ANSI-SQL-Syntax anstelle der Oracle-spezifischen hierarchischen Abfragesyntax zu verwenden. – SriniV

+0

@realspirituals - sicher, solange Sie ' Wenn Sie Oracle 11g oder höher verwenden, können Sie anstelle einer hierarchischen Abfrage ein rekursives CTE verwenden. Hoffentlich meinst du das! Ich habe eine Version hinzugefügt, die das zu meiner Antwort verwendet. –

+0

Ausgezeichnete Antwort Kumpel. Das gab mir einen guten Ausgangspunkt, um zu graben. – SriniV