【问题标题】:Oracle using Temp tables in stored procedureOracle 在存储过程中使用临时表
【发布时间】:2018-03-23 18:04:22
【问题描述】:

我有一个使用临时表的查询,我想将它添加到存储过程中。但是在编译时我得到“错误(10,1):PLS-00428:这个SELECT语句中应该有一个INTO子句”

举例

    WITH T1 as
    (
      SELECT ID, CREATED_DATE, LOOKUP_ID
      FROM TEST1
    ),T2 as
    (
      SELECT ID, CREATED_DATE, LOOKUP_ID
      FROM TEST2
    )
    SELECT * from T1
    minus
    SELECT * from T2

    RESULTS
    ID CREATED_D  LOOKUP_ID
---------- --------- ----------
    217322 11-DEC-16          1

作为存储过程添加:

create or replace PROCEDURE "TEST"
(
  T IN OUT SYS_REFCURSOR
) AS
BEGIN

  WITH T1 as
  (
    SELECT ID, CREATED_DATE, LOOKUP_ID
    FROM TEST1
  ), T2 as
  (
    SELECT ID, CREATED_DATE, LOOKUP_ID
    FROM TEST2
  )
  SELECT * from T1
  minus
  SELECT * from T2
end;

END;

错误(7,1):PLS-00428:此 SELECT 语句中需要一个 INTO 子句

我确实看到了 PLS-00428: an INTO clause is expected in this SELECT statement 但它正在使用 INSERTS,我不想这样做。我只想使用临时表。

【问题讨论】:

  • 你真的应该缩进。
  • 我缩进了...你现在看到你的问题了吗?
  • 应始终将所选列读入 PL/SQL 变量,然后使用 DBMS_OUTPUT.PUT_LINE 打印。从过程或函数执行时,不会自动显示查询结果。

标签: sql oracle plsql


【解决方案1】:

我们需要在 PL/SQL 变量中处理查询的输出。

create or replace PROCEDURE "TEST"
(
  T IN OUT SYS_REFCURSOR
) AS

cursor c_cur is
 WITH T1 as
  (
    SELECT ID, CREATED_DATE, LOOKUP_ID
    FROM TEST1
  ), T2 as
  (
    SELECT ID, CREATED_DATE, LOOKUP_ID
    FROM TEST2
  )
  SELECT * from T1
  minus
  SELECT * from T2;
BEGIN
for r_cur in c_cur
loop
dbms_output.put_line('ID: '||r_cur.id ||'CREATED_DATE: ' ||r_cur.CREATED_DATE ||' LOOKUP_ID: '||r_cur.lookup_id);
end loop;
end;

【讨论】:

  • - 错误(40,30):PLS-00364:循环索引变量“R_CUR”使用无效
  • @HOGAN - IN OUT(删除了 IN)添加使用此出口和以上解决方案对我有用。
【解决方案2】:

你必须重写它;由于过程使用 refcursor,我假设您想使用 WITH factoring 子句作为它的来源。

Scott 的 DEPT 表的工作示例:

SQL> create or replace procedure p_test (t in out sys_refcursor)
  2  as
  3  begin
  4    open t for
  5       select t1.* from (select dname from dept) t1;
  6  end;
  7  /

Procedure created.

SQL>
SQL> var l_rc refcursor
SQL> exec p_test (:l_rc);

PL/SQL procedure successfully completed.

SQL> print :l_rc

DNAME
--------------
ACCOUNTING
RESEARCH
SALES
OPERATIONS

SQL>

或者,您的代码以相同的方式重写(希望我没有打错字):

create or replace procedure test (t in out sys_refcursor)
as
begin
  open t for
    select * from (select * from (select id, created_date, lookup_id
                                  from test1) 
                   minus
                   select * from (select id, created_date, lookup_id
                                  from test2)
                  );
end;

【讨论】:

  • 我无法重写查询(我添加的示例是通用的,实际一个是多个临时表并且非常大)。
  • 为什么不能重写呢? CTE 只是替换了我们多年来使用的内联视图,所以 - 我看不出有任何理由让您无法做到这一点。
猜你喜欢
  • 2015-02-15
  • 2011-10-29
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
相关资源
最近更新 更多