2017-06-15 2 views
0

Ich habe den folgenden Code:DBMS_SQL.TO_REFCURSOR Äquivalent in Oracle 10g

procedure Replace(sUser in Varchar2,sNomTable in varchar2,sColonne in varchar2,sID in Varchar2,nbCharAlterer IN NUMBER) is 

    l_cursor NUMBER; 
    l_return NUMBER; 
    l_ref_cursor SYS_REFCURSOR; 
    TYPE t_tab IS TABLE OF VARCHAR2(4000); 
    l_tab t_tab; 
    l_tab_Id t_tab; 
    sChaine VARCHAR2(4000 CHAR); 
    sqlReq CONSTANT VARCHAR2(1000):= 'select ' || sId || ',' || sColonne || ' from ' || sUser || '.' || sNomTable ; 

begin 
    -- 
    l_cursor := DBMS_SQL.open_cursor; 
    DBMS_SQL.parse(l_cursor, sqlReq, DBMS_SQL.NATIVE); 
    l_return := DBMS_SQL.EXECUTE(l_cursor); 
    -- Connvert from DBMS_SQL to a REF CURSOR. 
    l_ref_cursor := DBMS_SQL.to_refcursor(l_cursor); 

Hier bin ich die folgende Fehlermeldung erhalten:

pls 00302 component 'TO_REFCURSOR' must be declared 

seit meiner Oracle Version 10g.

Eine Idee, wie Sie das Äquivalent in Oracle 10g tun?

+1

Ok, ich denke es ist weil ich Oracle 10g benutze und to_refocursor nur für 11g Versionen und höher verfügbar ist. Irgendeine Idee, wie man das Äquivalent in Oracle 10g macht? – tabby

+3

Ich glaube nicht, dass Sie von DBMS_SQL in RefCursor in Oracle 10g konvertieren können. Sie müssen in DBMS_SQL bleiben und alle Operationen dort vornehmen. Es ist möglich - es ist nur mehr Code, den Sie schreiben müssen. –

+0

Wenn Sie von dbms_sql in native dynamische SQL in 10g wechseln möchten, warum starten Sie nicht mit nativen dynamischen SQL in erster Linie? Ihr Beispiel könnte ziemlich einfach konvertiert werden. – Boneist

Antwort

2

Hier ist, wie Sie nativem dynamischen SQL verwenden:

PROCEDURE p_replace(suser   IN VARCHAR2, 
        snomtable  IN VARCHAR2, 
        scolonne  IN VARCHAR2, 
        sid   IN VARCHAR2, 
        nbcharalterer IN NUMBER) IS 
    v_validate_sid_col_name VARCHAR2(32); 
    v_validate_scolonne_col_name VARCHAR2(32); 
    v_validate_suser VARCHAR2(32); 
    v_validate_snomtable VARCHAR2(32); 

    sqlreq VARCHAR2(2000); 

    refcur sys_refcur; 
BEGIN 
    -- Check the input values are valid identifiers (to avoid sql injection) 
    -- N.B. this does not check they are valid object names! 
    v_validate_sid_col_name := dbms_assert.qualified_sql_name(sid); 
    v_validate_scolonne_col_name := dbms_assert.qualified_sql_name(scolonne); 
    v_validate_suser := dbms_assert.qualified_sql_name(suser); 
    v_validate_snomtable := dbms_assert.qualified_sql_name(scolonne); 

    sqlReq := 'select ' || v_validate_sid_col_name || ',' || 
          v_validate_scolonne_col_name || 
      ' from ' || v_validate_suser || '.' || v_validate_snomtable; 

    -- or maybe you want to use execute immediate to bulk collect into arrays? 
    OPEN refcur FOR sqlreq; 

    ... 
END p_replace; 

Bitte beachte, dass ich den Namen des Verfahrens geändert haben, seit „ersetzen“ ist der Name eines bereits bestehenden integrierten Funktion, und deshalb nicht ein sehr guter Name zu verwenden.

Sie erwähnen nicht, was Sie mit den Ergebnissen Ihrer Abfrage tun werden, also war ich mir nicht sicher, ob das Öffnen eines Ref-Cursors genau das ist, was Sie tatsächlich benötigen, oder ob Bulk-Sammlung über execute sofort erfolgen würde besser für dich arbeiten.