我试图修改Oracle存储的过程以使用CTE而不是简单的选择语句。

我的过程看起来像这样:

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语句的一部分,因此不应包含半隆。

因此,在第三块或第四块的第三行的第二行上不应有半隆。第五块没有连续的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进行了转换,我想在结果中添加行数。我只是忘记了为 *添加别名

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-Server迁移到Oracle,但是存在一些较小的语法差异。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top