I'm trying to create pivot clause that gets it parameters from variable.
I have some test code like:
SELECT * FROM (
SELECT U.USER_ID, U.USER_NAME, E.EXAM_ID, EU.EXAM_DATE
FROM USERS U, EXAMS E, EXAM_USER EU
WHERE U.USER_ID = EU.USER_ID(+)
AND E.EXAM_ID(+) = EU.EXAM_ID
ORDER BY U.USER_ID
)
PIVOT (MAX(EXAM_DATE) FOR EXAM_ID IN ('3' AS "exam 3",'2' AS "exam 2",'1' AS "exam 1"))
order by 1
;
This works just fine. Then I declared the variable EXAM_IDS like:
DECLARE
EXAM_IDS VARCHAR2 (255);
BEGIN
SELECT LISTAGG('''' || EXAM_ID || ''' AS "' || EXAM_NAME || '"', ',')
WITHIN GROUP (ORDER BY EXAM_ID DESC)
INTO EXAM_IDS
FROM EXAMS;
END;
I'm pretty sure the variable EXAM_IDS has now a string as used in pivot clause(?) but I don know how to combine these two:
DECLARE
EXAM_IDS VARCHAR2 (255);
BEGIN
SELECT LISTAGG('''' || EXAM_ID || ''' AS "' || EXAM_NAME || '"', ',')
WITHIN GROUP (ORDER BY EXAM_ID DESC)
INTO EXAM_IDS
FROM EXAMS;
END;
SELECT * FROM (
SELECT U.USER_ID, U.USER_NAME, E.EXAM_ID, EU.EXAM_DATE
FROM USERS U, EXAMS E, EXAM_USER EU
WHERE U.USER_ID = EU.USER_ID(+)
AND E.EXAM_ID(+) = EU.EXAM_ID
ORDER BY U.USER_ID
)
PIVOT (MAX(EXAM_DATE) FOR EXAM_ID IN (' || EXAM_IDS || '))
order by 1
;
And this does not work. Is there a way to do this or should I just run two separate SQL queries?
More info about this setup (like my classes) can be found from Using Oracle combine three tables to one with PIVOT
For 12c and above, you may use
DBMS_SQL.RETURN_RESULT
by opening aREFCURSOR
for the dynamicPIVOT
query.I have removed the notorious
(+)
syntax forleft join
, always use the ANSIjoin
syntax.For 11g, you may use a bind variable and
print
command ( works in sqlplus and in sql developer/Toad when run as script (F5))