Frage

Diese Frage ähnelt einigen anderen, die ich auf Stackoverflow gefunden habe, aber die Unterschiede sind für mich signifikant genug, um eine neue Frage zu rechtfertigen. Hier ist es also:

Ich möchte ein Ergebnis aus dynamischem SQL in Oracle erhalten und es dann als Ergebnis in einem SQLDEveloter-ähnlichen Tool anzeigen, als hätte ich die dynamische SQL-Anweisung direkt ausgeführt. Dies ist im SQL -Server unkompliziert. Um konkret zu sein, finden Sie hier ein Beispiel von SQL Server, das ein Ergebnis in SQL Server Management Studio oder Query Explorer zurückgibt:

EXEC sp_executesql N'select * from countries'

Oder besserer:

DECLARE @stmt nvarchar(100)
SET @stmt = N'select * from countries'
EXEC sp_executesql @stmt

Die Frage "Wie kann ich ein Ergebnis- / Cursor aus einem anonymen Block von Oracle PL / SQL zurückgeben, der dynamische SQL ausführt?" befasst sich mit der ersten Hälfte des Problems-dynamische SQL in einen Cursor ausführen. Die Frage "So machen Sie Oracle Procedure -Rückgabe -Ergebnissätze" Bietet eine ähnliche Antwort. Die Websuche hat viele Variationen desselben Themas enthüllt, die alle nur die erste Hälfte meiner Frage behandeln. ich fand dieser Beitrag Erklären Sie, wie es in Sqldeveloper geht, aber das verwendet ein wenig Funktionalität von SQLDEVEVELDER. Ich verwende tatsächlich ein benutzerdefiniertes Abfragetool, daher brauche ich die Lösung, um im SQL-Code in sich geschlossen zu sein. Dieses benutzerdefinierte Abfragetool verfügt ebenfalls nicht um die Ausgabe von Druckausgaben (dbms_output.put_line). Es wird nur Ergebnissätze angezeigt. Hier ist noch eine weitere mögliche Allee Verwenden von 'Sofortiger ... Bulk Collect', aber dieses Beispiel macht die Ergebnisse erneut mit einer Schleife von DBMS_OUTPUT.PUT_LINE -Anweisungen. Dieser Link Versuche, das Thema anzugehen, aber die Frage wurde dort auch nie ganz beantwortet.

Angenommen, dies ist möglich, werde ich eine weitere Bedingung hinzufügen: Ich möchte dies tun, ohne eine Funktion oder ein Verfahren definieren zu müssen (aufgrund begrenzter DB -Berechtigungen). Das heißt, ich möchte einen in sich geschlossenen PL/SQL-Block mit dynamischer SQL ausführen und ein Ergebnis in SQLDEVEVELDER oder ein ähnliches Tool zurückgeben.


Also zusammenfassen:

  • Ich möchte eine beliebige SQL -Anweisung (daher dynamische SQL) ausführen.
  • Die Plattform ist Oracle.
  • Die Lösung muss ein PL/SQL -Block ohne Verfahren oder Funktionen sein.
  • Die Ausgabe muss als kanonisches Ergebnissatz erzeugt werden. Keine Druckanweisungen.
  • Die Ausgabe muss als Ergebnis in SQLDEVEVELDER verteilt werden, ohne dass SQLDEveloter -Spezialfunktionen verwendet werden.

Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Sie scheinen nach einem Stück PL/SQL -Code zu fragen, der eine willkürliche Abfrage -Rückgabe -Ergebnismenge unbestimmter Struktur und "Vorwärts-/Umstrukturierung" erfordert, die auf irgendeine Weise so eingestellt werden ".

Wenn ja, schauen Sie sich die dbms_sql für dynamische SQL an. Es verfügt über eine Prozedur für beschreibe_columns, die die Spalten aus einer dynamischen Auswahlanweisung zurückgibt. Die Schritte, die Sie brauchen würden, sind,

  1. Die Aussage analysieren
  2. Beschreiben Sie den Ergebnissatz (Spaltennamen und Datentypen)
  3. Rufen Sie jede Zeile ab und rufen Sie für jede Spalte die Funktion der DataType -abhängigen Funktion auf, um diesen Wert in eine lokale Variable zurückzugeben
  4. Platzieren Sie diese lokalen Variablen in eine definierte Struktur, um in die Anrufumgebung zurückzukehren (z. B. konsistente Spaltennamen [wie col_1, col_2] wahrscheinlich alle Varchar2)

Als Alternative können Sie versuchen, die Abfrage in eine zu bauen Xmlforest Aussage und analysieren Sie die Ergebnisse aus dem XML.


Hinzugefügt: Im Gegensatz zu SQL Server wird ein Oracle PL/SQL -Anruf nicht "natürlich" ein einzelnes Ergebnissatz zurückgegeben. Es kann einen oder mehrere Ref Cursors öffnen und an den Kunden zurückgeben. Es wird dann zur Verantwortung des Kunden, Datensätze und Spalten von diesen Ref Cursors abzurufen. Wenn Ihr Kunde damit nicht umgehen/nicht, können Sie keinen PL/SQL -Anruf verwenden. Eine gespeicherte Funktion kann einen vordefinierten Sammlungstyp zurückgeben, mit dem Sie so etwas wie "Auswählen * aus der Tabelle (func_name (" aus Ländern auswählen) "ermöglichen können. Die Funktion kann jedoch DML nicht ausführen (Aktualisieren/Löschen/Einfügen/Zusammenführen), da sie ein Konzept der Konsistenz für diese Abfrage wegblasen. Plus die zurückgegebene Struktur ist so festgelegt, dass

select * from table(func_name('select * from countries'))

Muss dieselbe Spaltenmenge zurückgeben (Spaltennamen und Datentypen) wie

select * from table(func_name('select * from persons'))

Es ist möglich, dass eine solche Funktion eine dynamische Abfrage übernimmt und in einen vordefinierten Spaltensatz (col_1, col_2 usw.) verwendet wird, damit sie konsequent zurückgegeben werden kann. Aber ich kann nicht sehen, was der Sinn davon sein würde.

Andere Tipps

Versuchen Sie es mit diesen.

DECLARE
  TYPE EmpCurTyp  IS REF CURSOR;
  v_emp_cursor    EmpCurTyp;
  emp_record      employees%ROWTYPE;
  v_stmt_str      VARCHAR2(200);
  v_e_job         employees.job%TYPE;
BEGIN
  -- Dynamic SQL statement with placeholder:
  v_stmt_str := 'SELECT * FROM employees WHERE job_id = :j';

  -- Open cursor & specify bind argument in USING clause:
  OPEN v_emp_cursor FOR v_stmt_str USING 'MANAGER';

  -- Fetch rows from result set one at a time:
  LOOP
    FETCH v_emp_cursor INTO emp_record;
    EXIT WHEN v_emp_cursor%NOTFOUND;
  END LOOP;

  -- Close cursor:
  CLOSE v_emp_cursor;
END;


declare
  v_rc    sys_refcursor;
begin
   v_rc := get_dept_emps(10);  -- This returns an open cursor
   dbms_output.put_line('Rows: '||v_rc%ROWCOUNT);
   close v_rc;
end;

Weitere Beispiele finden Sie hier. http://forums.oracle.com/forums/thread.jspa?threadid=886365&tstart=0

In Toad werden Sie beim Ausführen des folgenden Skripts für die Art von v_result aufgefordert. Aus der Auswahlliste der Typen aus dem Auswahl von Cursor werden die Ergebnisse dann im Datengitter von Toad angezeigt (die Excel -Tabelle wie Ergebnis). Wenn Sie jedoch mit Cursors als Ergebnisse arbeiten, sollten Sie immer zwei Programme (den Client und den Server) schreiben. In diesem Fall wird 'Toad' der Kunde sein.

DECLARE
   v_result      sys_refcursor;
   v_dynamic_sql   VARCHAR2 (4000);
BEGIN
   v_dynamic_sql := 'SELECT * FROM user_objects where ' || ' 1 = 1';

   OPEN :v_result FOR (v_dynamic_sql);
END;

Es kann einen ähnlichen Mechanismus im SQL -Entwickler von Oracle geben, auch die Bindung zu fordern.

Das, was ich mir vorstellen kann, ist, eine dynamische Ansicht zu erstellen, für die die Erlaubnis erforderlich ist. Dies wird sicherlich die Verwendung eines PL/SQL -Blocks beinhalten und Eine SQL -Abfrage und keine Prozedur/Funktion. Jede dynamische Abfrage kann jedoch aus dem Ergebnisraster konvertiert und angesehen werden, da sie als ausgewählte Abfrage ausgeführt wird.

DEFINE view_name = 'my_results_view';
SET FEEDBACK OFF
SET ECHO OFF
DECLARE
  l_view_name VARCHAR2(40)     := '&view_name';
  l_query     VARCHAR2(4000)   := 'SELECT 1+level as id,
                                  ''TEXT''||level as text  FROM DUAL ';
  l_where_clause VARCHAR2(4000):= 
                           ' WHERE TRUNC(1.0) =  1 CONNECT BY LEVEL < 10';
BEGIN
     EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW '
                       || l_view_name
                       || ' AS '
                       || l_query
                       || l_where_clause;
END;
/
 select * from &view_name;

enter image description here

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