質問

単純な選択ステートメントの代わりに、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に移動するのに役立つようですが、いくつかの小さな構文の違いがあります。

ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top