Wie die Rückkehr ein allgemeiner Tabellenausdruck als REFCURSOR von einer in Oracle gespeicherten Prozedur?
-
16-10-2019 - |
Frage
Ich habe versucht zu ändern, eine gespeicherte Oracle-Prozedur zu verwenden, CTE statt einer einfachen Select-Anweisung.
Meine Vorgehensweise sah so aus:
Create or replace Myproc ( MyRefCursor IN OUT SYS_REFCURSOR)
as
begin
Open MyRefCursor for
Select * from ...something ...;
end;
/
Ich schrieb diese Abfrage:
Select * from ...something ...;
Als diese CTE:
with MyCTE As (
... ;
)
Select * from MyCTE;
Öffnen eines cursor-dieser Weg funktioniert nicht:
Open MyRefCursor for
with MyCTE As (
... ;
)
Select * from MyCTE;
Noch ist dies:
with MyCTE As (
... ;
)
Open MyRefCursor for
Select * from MyCTE;
Lösung
Da der CTE Teil derselben SQL -Anweisung ist, sollte er kein Semikolon enthalten.
Es sollte also kein Semikolon in der zweiten Zeile des dritten Blocks oder in der dritten Zeile des vierten Blocks geben. Der fünfte Block hat keine zusammenhängende SQL -Anweisung.
Andere Tipps
Eine vollständige, sehr grundlegendes Beispiel für die Verwendung einer gespeicherten Prozedur, ohne Eingabe-parameter:
Einige demo-Daten:
CREATE TABLE DEMO(
id NUMBER(10),
type NUMBER(10),
code varchar2(20)
);
Insert INTO DEMO values (1, 0, 'a');
Insert INTO DEMO values (2, 0, 'b');
Insert INTO DEMO values (3, 0, 'c');
Insert INTO DEMO values (4, 1, 'd');
Insert INTO DEMO values (5, 1, 'e');
Insert INTO DEMO values (6, 1, 'f');
SELECT * from DEMO;
Jetzt eine einfache gespeicherte Prozedur mit einem trivialen CTE:
create or replace procedure return_from_simple_cte
(
MyRefCursor IN OUT SYS_REFCURSOR
)
AS
BEGIN
Open MyRefCursor for
WITH My_CTE AS(
SELECT * FROM DEMO WHERE Type = 1
)
Select * FROM My_CTE;
END;
/
Und schließlich ein test-Anruf für sqlplus oder TOAD
VAR R REFCURSOR
EXEC return_from_simple_cte (:R)
PRINT r
Hintergrund zu dieser Frage:
Ich habe die transformation von der Select-Anweisung der CTE auf SQL-Server einen wollte ich hinzufügen, dass Zeilen-Nummern zu dem Ergebnis.Ich habe einfach vergessen, dass ein alias hinzufügen, um die *
create or replace PROCEDURE TEChange
(
MyRefCursor IN OUT SYS_REFCURSOR
,p_TERefnr NUMBER
)
AS
BEGIN
Open MyRefCursor for
WITH TE_CTE AS (
SELECT TeRefnr
FROM vSYSTE
WHERE TERefnr <> p_TERefnr
)
Select
ROW_NUMBER() over(order by TERefnr) Nr,
t.*
from TE_CTE t;
END;
/
nonreursive CTEs scheinen zu helfen, die Migration von SQL Server zu Oracle, aber es gibt einige geringfügige syntax-Unterschiede.