2016-06-24 7 views
1

Was ich tun möchte: Abrufen von Daten aus einer Tabelle mithilfe der benutzerdefinierten Funktion und Verwendung von benutzerdefinierten Typen.Abrufen von Zeilen aus der Tabelle über die Funktion

Die Struktur meiner Tabelle ist unten wie:

create table ACCOUNTCONTRACT 
(
    accountcode_   VARCHAR2(255 CHAR), 
    accountmig_    NUMBER(1), 
    accountnumber_   VARCHAR2(25 CHAR) not null, 
    accountpk_    NUMBER(19), 
    addinfo1_    VARCHAR2(255 CHAR), 
    addinfo2_    VARCHAR2(255 CHAR), 
... 

was ich getan habe:

meine Benutzerdefinierte Typen erstellen
CREATE OR REPLACE TYPE "FO_OUTPUT" AS OBJECT 
(
    NUMCPT  VARCHAR2(10), 
    ACTIONACCOUNT VARCHAR2(50) 
) 

UND

CREATE OR REPLACE TYPE "FO_OUTPUT_TABLE" AS TABLE OF FO_OUTPUT 

Meine Funktion ist:

CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS 
    RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
    TMPLINE FO_OUTPUT; 
    PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       INTO TMPLINE.NUMCPT, TMPLINE.ACTIONACCOUNT 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := TMPLINE; 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 

Wenn ich jetzt folgendes ausführe: `SELECT * FROM TABLE (OUTPUT_FO) Alles, was ich bekomme, sind 10 leere Zeilen.

Was ist falsch mit meinem Code. Thnx

Antwort

1
CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
TMPLINE FO_OUTPUT; 
PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN 
    TMPLINE := FO_OUTPUT('', ''); 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       --INTO TMPLINE.NUMCPT, TMPLINE.ACTIONACCOUNT << this does not work 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    -- But this:     
    TMPLINE.numcpt:= i.numcpt; 
    TMPLINE.ACTIONACCOUNT:= i.ACTIONACCOUNT; 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := TMPLINE; 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 
+0

ich verwirrt die Verwendung von "select into". musste den zusammengesetzten Typ initialisieren. –

+0

rechts, 'TMPLINE' muss initialisiert werden. –

0

Hier ist, wie ich tat, damit es funktioniert:

CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS 
    RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
BEGIN 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := FO_OUTPUT(I.NUMCPT, I.ACTIONACCOUNT); 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 
+1

In diesem Fall wird 'TMPLINE' nicht benötigt. –

+0

@FrankOckenfuss: Sie sind in Ordnung –

1

Verwendung BULK COLLECT INTO:

CREATE OR REPLACE FUNCTION OUTPUT_FO 
RETURN FO_OUTPUT_TABLE 
AS 
    RETVAL FO_OUTPUT_TABLE; 
BEGIN 
    SELECT FO_OUTPUT(
      SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10), 
      ACC.ACCOUNTNUMBER_ 
     ) 
    BULK COLLECT INTO RETVAL 
    FROM ACCOUNTCONTRACT ACC 
    WHERE ROWNUM < 10; 

    RETURN RETVAL; 
END OUTPUT_FO; 
/
+0

unter Berücksichtigung der Geschwindigkeit und Leistung, Ist BULK effizienter und schneller als der Code, den ich im Antwortabschnitt geschrieben habe? –

+1

Es scheint, dass Oracle (https://community.oracle.com/thread/2353407?start=0&tstart=0) eine "FOR" -Schleife des Cursors (intern) in eine Massensammlung umwandeln wird (wenn es möglich ist). Es kann also einen kleinen Leistungsunterschied geben, aber Sie können auch vergleichen, ob der Code einfacher ist (lesen und pflegen). Die einfachste Methode, um die leistungsstärkere Methode zu finden, besteht darin, sie auf Ihrem System zu profilieren. – MT0

Verwandte Themen