SYS_REFCURSOR
एक संग्रहीत फ़ंक्शन के भीतर (जैसे। PL/SQL सीधे SQL का उपयोग करने के बजाय उपयोग किया जाता है ) का उपयोग गतिशील रूप से उत्पन्न परिणाम सेट प्राप्त करने के लिए किया जा सकता है (जैसे। डायनामिक पिवट ) इस मामले में, सशर्त एकत्रीकरण के लिए एक स्ट्रिंग उत्पन्न होती है:
CREATE OR REPLACE FUNCTION get_passengers_rs RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_str VARCHAR2(32767);
BEGIN
SELECT LISTAGG('MAX(CASE WHEN rn = '||lvl||' THEN age||''(''||passengers||'')'' END)
AS "Age'||lvl||'"' ,',') WITHIN GROUP (ORDER BY 0)
INTO v_str
FROM ( SELECT level AS lvl
FROM dual
CONNECT BY level <= (SELECT MAX(COUNT(*)) FROM t GROUP BY ID ) ) t;
v_sql :=
'SELECT ID, '|| v_str ||'
FROM
(
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
FROM t
)
GROUP BY ID';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
मैंने प्रत्येक डेटा को अच्छी तरह से अलग करने के लिए यात्रियों के नाम भी जोड़े।
फिर नीचे दिया गया कोड चलाएँ:
VAR rc REFCURSOR
EXEC :rc := get_passengers_rs;
PRINT rc
अपेक्षित परिणाम सेट देखने के लिए SQL डेवलपर की कमांड लाइन से।
उपरोक्त कोड इस SQL स्ट्रिंग को उत्पन्न करता है (v_sql ) वर्तमान में मौजूदा डेटा के लिए
SELECT ID, MAX(CASE WHEN rn = 1 THEN age||'('||passengers||')' END) AS "Age1",
MAX(CASE WHEN rn = 2 THEN age||'('||passengers||')' END) AS "Age2",
MAX(CASE WHEN rn = 3 THEN age||'('||passengers||')' END) AS "Age3"
FROM
(
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
FROM t
)
GROUP BY ID
जो पैदावार
ID Age1 Age2 Age3
123456 58(Marie) 65(Ben)
123458 32(Aaron) 18(Caroline) 37(Stephanie)
परिणाम सेट के रूप में।