Frage

Ich brauche dynamische SQL-Ausführung auf Oracle verwenden, wo ich weiß nicht, die genaue Anzahl der Bind-Variablen in der SQL vor der Laufzeit verwendet wird.

Gibt es eine Möglichkeit, eine variable Anzahl von Bind-Variablen im Aufruf zu verwenden, irgendwie EXECUTE IMMEDIATE?

Insbesondere muss ich passieren ein Parameter in das Unbekannte SQL, aber ich weiß nicht, wie oft wird es dort verwendet werden.

Ich habe versucht, so etwas wie

EXECUTE IMMEDIATE 'SELECT SYSDATE FROM DUAL WHERE :var = :var' USING 1;

Aber es warf zurück mit ORA-01008: not all variables bound.

War es hilfreich?

Lösung

Sie können dies nicht mit EXECUTE IMMEDIATE. Allerdings können Sie dies tun, indem Oracle DBMS_SQL Paket. Die Database Application Developer Guide hat ein Vergleich zwischen dem EXECUTE IMMEDIATE Sie mit und dbms_sql Methoden vertraut sind. Diese Seite Dokumente DBMS_SQL, aber hat einige Beispiele (oben verlinkten), die Sie (Beispiel 1 ist ein einfacher Fall von einer Anweisung ausgeführt wird, die eine beliebige Anzahl von bind-Variablen haben könnte) beginnen sollte. DBMS_SQL ist viel umständlicher aus einer Codierung Perspektive, aber es ermöglicht es Ihnen, nur um etwas zu tun, können Sie sich vorstellen.

Mehrere Instanzen der Bind Variable in der SQL auftreten darf. Allerdings müssen Sie den Namen kennen, als Bindevariable verwendet werden (zum Beispiel: var in Ihrem Fall)., Um es in DBMS_SQL.BIND_VARIABLE passiert

Andere Tipps

Sie können auch durch die Verwendung einer WITH Anweisung, um dieses Problem zu umgehen. Im Allgemeinen mit DBMS_SQL ist besser, aber manchmal ist dies ein einfacher Weg:

BEGIN
    EXECUTE IMMEDIATE 'WITH var AS (SELECT :var FROM dual) SELECT SYSDATE FROM DUAL WHERE (SELECT * FROM var) = (SELECT * FROM var)' USING 1;
END;

Das Thread auf AskTom deckt das Thema im Detail

In Ihrem Fall, wenn Sie einen Parameter oder keine übergeben möchten, können Sie zwei Abfragen erstellen, die einen einzelnen Parameter haben und in einem dieser Abfrage nicht verwendet wird (dh das Prädikat ist immer wahr) wie folgt aus:

-- query1
SELECT * FROM DUAL WHERE dummy = :x;

-- query2
SELECT * FROM DUAL WHERE nvl(:x, 1) IS NOT NULL;

Sie können sich wahrscheinlich das Prädikat verfeinern, so dass das Optimierungsprogramm wird verstehen, dass es immer wahr ist.

  

Genauer gesagt, ich brauche einen Parameter in das Unbekannte SQL passieren, aber ich weiß nicht, wie oft wird es dort verwendet werden.

Ich lief tatsächlich in dieses exakt gleiche Problem vor ein paar Tagen, und ein Freund mit mir geteilt, einen Weg, genau das mit EXECUTE IMMEDIATE zu tun.

Es geht um Erzeugen eines PLSQL Block in Bezug auf die SQL-Block selbst gegenüber. Wenn EXECUTE IMMEDIATE mit einem Block von PLSQL Code verwenden, können Sie Variablen mit Namen binden im Gegensatz zu nur durch Position.

überprüfen Sie mein Beispiel / Code und auf meinem eigenen ähnlichen Frage / Antwort-Thread:

Man kann dbms_sql wie Steve Broberg verwenden erklärt aber die resultierende Cursor kann (lesen) in einer Menge von Kunden nicht verzehrt werden. Oracle 11 hat eine Konvertierungsfunktion ( dbms_sql.to_refcursor ), der es ermöglicht, eine dbms_sql Cursor auf einen ref Cursor zu konvertieren, aber man kann nicht verbrauchen diese ref Cursor in einer .Net-Anwendung aus irgendeinem Grunde umgewandelt. Man kann eine normale ref Cursor in .net verbraucht aber keine ref Cursor, die dbms_sql Cursor verwendet werden, um.

Also, welche Art von Client raubend diesen Cursor sein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top