Aanvankelijk zag ik geen elegantere oplossing dan het maken van een tijdelijke tabel.
Ik zat te denken, wat een ongemakkelijk dialect van SQL Oracle is:
- Waarom niet ALS TABEL BESTAAT, TABEL VERWIJDEREN?
- Waarom moet ik IMMEDIATE UITVOEREN met een string? Waarom kan ik DROP TABLE TEMP niet gewoon zelf doen?
- Waarom kan ik geen ORDER BY gebruiken zonder tussen haakjes op ANCHOR te nesten?
- Waarom kan ik geen ORDER BY hebben op recursieve SELECT na UNION ALL?
- SQL WITH heeft standaardisatie nodig. Andere databasedialecten vereisen niet dat kolomnamen tussen haakjes staan in de WITH-instructie. Als je dat niet doet, krijg je een betekenisloze ALIAS-fout, op het punt van de recursieve join na UNION ALL.
- Paginering:zie hier Geen LIMIT / OFFSET
DECLARE
v_c NUMBER;
BEGIN
SELECT COUNT(*) INTO v_c FROM user_tables WHERE TABLE_NAME = 'TEMP';
IF v_c = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE TEMP';
END IF;
END;
CREATE TABLE TEMP AS (
SELECT * FROM (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NOT NULL
ORDER BY JOBMST_PRNTID, JOBMST_NAME
)
);
WITH J1(JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, LVL) AS (
SELECT * FROM (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, 1
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NULL
ORDER BY JOBMST_NAME
)
UNION ALL
SELECT J2.JOBMST_ID, J2.JOBMST_NAME, J2.JOBMST_PRNTID, J2.JOBMST_TYPE, J1.LVL + 1
FROM TEMP J2
INNER JOIN J1 ON J2.JOBMST_PRNTID = J1.JOBMST_ID
WHERE J2.JOBMST_PRNTID IS NOT NULL
)
SEARCH DEPTH FIRST BY JOBMST_ID SET DISP_SEQ
SELECT *
FROM J1
ORDER BY DISP_SEQ;
Toen (mathguy op het Oracle Community Forum) wees me erop dat mijn ZOEKDIEPTE EERST gewoon door JOBMST_NAME had moeten zijn.
Dan valt alles op zijn plaats:
WITH J1(JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, LVL) AS (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, 1
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NULL
UNION ALL
SELECT J2.JOBMST_ID, J2.JOBMST_NAME, J2.JOBMST_PRNTID, J2.JOBMST_TYPE, J1.LVL + 1
FROM TIDAL.JOBMST J2
INNER JOIN J1 ON J2.JOBMST_PRNTID = J1.JOBMST_ID
WHERE J2.JOBMST_PRNTID IS NOT NULL
)
SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQ
SELECT *
FROM J1
ORDER BY DISP_SEQ