Question

J'ai essayé de modifier une procédure stockée Oracle pour utiliser un CTE au lieu d'une simple déclaration Select.

Ma procédure ressemblait à ceci:

Create or replace Myproc ( MyRefCursor  IN OUT SYS_REFCURSOR)
as
begin
    Open MyRefCursor for
        Select * from ...something ...;


end;
/

Je réécrit cette requête:

   Select * from ...something ...;

Comme ce CTE:

with MyCTE As (
    ... ;
)
Select * from MyCTE;    

Ouverture d'un curseur de cette façon ne fonctionne pas:

Open MyRefCursor for
with MyCTE As (
    ... ;
)
Select * from MyCTE;    

ne fait ceci:

with MyCTE As (
    ... ;
)
Open MyRefCursor for
Select * from MyCTE;    
Était-ce utile?

La solution

Étant donné que le CTE fait partie de la même instruction SQL, il ne doit pas contenir un point-virgule.

Donc, il ne devrait pas être sur la deuxième virgule ligne du troisième bloc ou la troisième ligne du quatrième bloc. Le cinquième bloc ne dispose pas d'une instruction SQL contiguë.

Autres conseils

Un exemple très basique complet en utilisant une procédure stockée sans paramètre d'entrée:

Certaines données de démonstration:

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;

Maintenant, une procédure stockée simple à l'aide d'un CTE trivial:

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;
/

Et enfin un appel test pour sqlplus ou TOAD

VAR R REFCURSOR
EXEC return_from_simple_cte (:R)
PRINT r

Contexte de cette question:

Je l'ai fait la transformation de la instruction_select à CTE sur SQL-server un que je voulais ajouter une ligne numéros au résultat. J'oublie simplement que ajouter un alias à la *

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 semblent aider à migrer de SQL Server pour Oracle, mais il y a quelques différences de syntaxe mineures.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top