Zpočátku jsem neviděl elegantnější řešení než vytvoření dočasné tabulky.
Přemýšlel jsem, jaký je to trapný dialekt SQL Oracle:
- Proč ne, POKUD EXISTUJE TABULKA, DELETE TABULKU?
- Proč musím provést EXECUTE IMMEDIATE pomocí řetězce? Proč nemohu jednoduše provést DROP TABLE TEMP samostatně?
- Proč nemohu mít ORDER BY bez vnoření v závorkách na ANCHOR?
- Proč nemohu mít ORDER BY na rekurzivním SELECT po UNION ALL?
- SQL S potřebuje standardizaci. Jiné dialekty databáze nevyžadují, aby byly názvy sloupců v závorkách v příkazu WITH. Pokud to neuděláte, dostanete nějakou nesmyslnou chybu ALIAS v bodě rekurzivního spojení po UNION ALL.
- Paginace:viz zde Bez LIMITU / 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;
Pak mě (mathguy na fóru Oracle Community Forum) upozornil, že moje HLOUBKA HLEDÁNÍ FIRST měla být právě od JOBMST_NAME.
Pak to všechno zapadne na své místo:
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