OracleストアドプロシージャからRefCursorとしてCTEを返す方法は?
-
16-10-2019 - |
質問
単純な選択ステートメントの代わりに、CTEを使用するためにOracleストアドプロシージャを変更しようとしました。
私の手順は次のように見えました:
Create or replace Myproc ( MyRefCursor IN OUT SYS_REFCURSOR)
as
begin
Open MyRefCursor for
Select * from ...something ...;
end;
/
このクエリを書き直しました:
Select * from ...something ...;
このCTEとして:
with MyCTE As (
... ;
)
Select * from MyCTE;
この方法でカーソルを開くと機能しません:
Open MyRefCursor for
with MyCTE As (
... ;
)
Select * from MyCTE;
これもそうではありません:
with MyCTE As (
... ;
)
Open MyRefCursor for
Select * from MyCTE;
解決
CTEは同じSQLステートメントの一部であるため、セミコロンを含めるべきではありません。
したがって、3番目のブロックの2行目または4番目のブロックの3番目の行にセミコロンはないはずです。 5番目のブロックには、隣接するSQLステートメントがありません。
他のヒント
入力パラメーターのないストアドプロシージャを使用した完全な非常に基本的な例:
いくつかのデモデータ:
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;
今、些細な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;
/
そして最後に、SQLPLUSまたはTOADのテスト呼び出し
VAR R REFCURSOR
EXEC return_from_simple_cte (:R)
PRINT r
この質問の背景:
SQL-ServerでCTEにSelect-Statementの変換を行いました。結果にRow Numbersを追加したいと思いました。私は単に *にエイリアスを追加することを忘れています *
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;
/
非脱毛性CTEは、SQLサーバーからOracleに移動するのに役立つようですが、いくつかの小さな構文の違いがあります。
所属していません dba.stackexchange