2009-06-17 8 views
0

Alle,EXECUTE IMMEDIATE mit USING-Klausel gibt Fehler

Ich bin sehr neu in der Regel zu Stored Procedures, aber ich habe Schwierigkeiten vor allem mit dem in Oracle. Ich habe ein sehr einfaches Beispiel dafür erstellt, was ich erreichen möchte, und ich bekomme immer noch den gleichen Fehler mit dieser vereinfachten Version.

Das Beispiel gespeicherte Prozedur ist wie folgt:

CREATE OR REPLACE PROCEDURE ashish_test 
AUTHID CURRENT_USER IS 
BEGIN 
    DECLARE 
      v_tab  VARCHAR2(50); 
      v_strSQL VARCHAR2(50); 
    BEGIN 
      v_strSQL := 'SELECT * FROM :1'; 
      v_tab := 'ex.emp'; 
      EXECUTE IMMEDIATE v_strSQL USING v_tab; 
    END; 
END; 

Wenn ich die oben gespeicherte Prozedur CALL ashish_test() nennen, die ich erhalten:

Error Message http://web1.twitpic.com/img/12831839-06a3ea536df5d5a0a839eb83d9e59d25.4a3936b8-scaled.jpg

Basierend auf this article (Suchen Sie nach Beispiel 7- 1), USING Schlüsselwort sollte den nummerierten Platzhalter (:1) innerhalb v_strSQL durch den ingespeicherten Wert ersetzen. Ich bekomme jedoch immer einen ungültigen Tabellenfehler. Ich vermute es ist, weil EXECUTE IMMEDIATE ist nicht in der Lage, den Platzhalter mit dem Wert aus irgendeinem Grund zu ersetzen, aber ich bin mir nicht sicher, warum das ist. Weiß jemand, ob ich hier etwas Dummes mache?

Ich verwende dies auf Oracle 10g Datenbank & mit PL/SQL Developer.

+0

Verwandte: [Warum kann ich nicht Bind-Variablen in DDL/SCL-Anweisungen in dynamischen SQL verwenden ?] (http://stackoverflow.com/q/25489002/1461424) – Krumia

Antwort

1

Die USING-Klausel ist nur für Bind-Variablen (d. H. Wo Sie Spaltennamen in einer SELECT-Anweisung verwenden würden), nicht Tabellennamen. Typische Anwendungen würde wie folgt aussehen:

Select col1 from table1 where col2 = :a 

Wenn Sie variable Tabellennamen verwenden möchten, verwenden Sie so etwas wie folgt aus:

  v_tab := 'ex.emp'; 
     v_strSQL := 'SELECT * FROM ' || v_tab; 
     EXECUTE IMMEDIATE v_strSQL; 
+0

Danke Diederik! Es ist seltsam, dass die Ausführungshierarchie von Oracle es unmöglich macht, Tabellennamen und Spaltennamen mithilfe der Platzhalter dynamisch zu ändern. Ich ging mit Ihrem Vorschlag für eine Problemumgehung. – tundal45

+1

Eine Bind-Variable kann nur einen einzelnen atomaren Wert enthalten - sie kann sich nicht auf eine Ergebnismenge beziehen. Eine FROM-Klausel kann sich nur auf Ergebnismengen beziehen (z. B. kann man nicht "SELECT * FROM 'abc'") - also macht eine Bind-Variable in diesem Kontext keinen Sinn. Mit dieser "Problemumgehung" können Sie die Ergebnismenge, auf die sich die Abfrage auswirkt, dynamisch ändern. –