Es ist ein bisschen chaotisch, aber Sie könnten es in einfachem SQL tun, beginnend mit einer hierarchischen Abfrage, um die verketteten Zeichenfolgen 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 bin davon ausgegangen, dass Ihre Tabelle wirklich eine andere Spalte hat, die Sie nicht gezeigt haben und die die Spaltenposition angibt. Wenn nicht, können Sie das irgendwie generieren - vielleicht basierend auf column_id für die Spalte der Basistabelle, alphabetisch oder was auch immer. Sie benötigen lediglich eine zusammenhängende Nummernfolge für die Connect-by-Klausel.
Sie können dann zwei Vereinigungen verwenden, um die Textteile für diese Spalten- und Pfadwerte zu erhalten (da sie separate Zeilen in Ihrer endgültigen Tabelle sein müssen), plus zusätzliche für SELECT ...
und FROM ...
Linien. Jede davon benötigt eine andere generierte Rangnummer. Diese können aus dem Ranking im 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;
Was mit Ihren 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 könnten es ein wenig variieren, indem Sie einen anderen CTE mit dem Join zwischen seeding_table
haben und ordercols_forview_cte
und das für die Gewerkschaft verwenden. Sie können die Pfade auch 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 das dann stattdessen verwenden; Dies führt die Verbindung zwischen diesem rekursiven CTE und der Seeding-Tabelle in einem anderen CTE wie oben erwähnt durch, aber Sie könnten einfach den hierarchischen Abfrage-CTE durch den rekursiven 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;
Was zum gleichen Ergebnis führt:
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