L'utilisation de sql dynamique pour un résultat où les colonnes sont inconnues au moment de l'exécution est un peu compliquée dans Oracle par rapport à certains autres RDMBS.
Étant donné que le type d'enregistrement pour la sortie est encore inconnu, il ne peut pas être défini à l'avance.
Dans Oracle 11g, une façon consiste à utiliser une procédure sans nom qui génère une table temporaire avec le résultat pivoté.
Sélectionnez ensuite les résultats de cette table temporaire.
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;
Renvois :
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Vous pouvez trouver un test sur db<>violon ici
Dans Oracle 11g, une autre astuce sympa (créée par Anton Scheffer) à utiliser peut être trouvée dans ce blog. Mais vous devrez ajouter la fonction pivot pour cela.
Le code source se trouve dans ce zip
Après cela, le SQL peut être aussi simple que ceci :
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Vous trouverez un test sur db<>violon ici