Die Verwendung von dynamischem SQL für ein Ergebnis, bei dem die Spalten zum Zeitpunkt der Ausführung unbekannt sind, ist in Oracle im Vergleich zu bestimmten anderen RDMBS etwas umständlich.
Da der Satztyp für die Ausgabe noch unbekannt ist, kann er nicht vorher definiert werden.
In Oracle 11g besteht eine Möglichkeit darin, eine namenlose Prozedur zu verwenden, die eine temporäre Tabelle mit dem Pivot-Ergebnis generiert.
Wählen Sie dann die Ergebnisse aus dieser temporären Tabelle aus.
declare
v_sqlqry clob;
v_cols clob;
begin
-- Generating a string with a list of the unique names
select listagg(''''||CCL||''' as "'||CCL||'"', ', ') within group (order by CCL)
into v_cols
from
(
select distinct CCL
from tableA
);
-- drop the temporary table if it exists
EXECUTE IMMEDIATE 'DROP TABLE tmpPivotTableA';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;
-- A dynamic SQL to create a temporary table
-- based on the results of the pivot
v_sqlqry := '
CREATE GLOBAL TEMPORARY TABLE tmpPivotTableA
ON COMMIT PRESERVE ROWS AS
SELECT *
FROM (SELECT ID, CCL, Flag FROM TableA) src
PIVOT (MAX(Flag) FOR (CCL) IN ('||v_cols||')) pvt';
-- dbms_output.Put_line(v_sqlqry); -- just to check how the sql looks like
execute immediate v_sqlqry;
end;
/
select * from tmpPivotTableA;
Rückgabe:
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Einen Test zu db<>fiddle finden Sie hier
In Oracle 11g findet sich in diesem Blog ein weiterer cooler Trick (erstellt von Anton Scheffer), der verwendet werden kann. Aber Sie müssen dafür die Pivot-Funktion hinzufügen.
Der Quellcode befindet sich in diesem Zip
Danach kann das SQL so einfach sein:
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Einen Test zu db<>fiddle finden Sie hier