PLSQL:在存储过程中使用动态查询时不显示输出

Posted

技术标签:

【中文标题】PLSQL:在存储过程中使用动态查询时不显示输出【英文标题】:PLSQL: No output displayed when using dynamic query inside Stored Procedure 【发布时间】:2016-03-10 11:49:53 【问题描述】:

我被要求创建一个 SP 来创建临时表并插入一些记录。

我正在为下面提到的相同准备一些示例代码,但没有显示输出。

create or replace procedure Test
is 
   stmt varchar2(1000);
   stmt2 varchar2(1000);
begin
    stmt := 'create global temporary table temp_1(id number(10))';
    execute immediate stmt;
    insert into temp_1(id) values (10);
    execute immediate 'Select * from temp_1';
    execute immediate 'Drop table temp_1';
    commit;
end;

当我通过 (Exec Test) 执行 SP 时,不显示所需的 O/P。

我希望显示“Select * from temp_1”的 O/P。但它没有发生。请提出我做错的地方。

【问题讨论】:

在 PL/SQL 中创建一个临时表、插入一些记录并随后删除该表是相当不常见的事情。通常有办法完全避免临时表。您手术的最终目标是什么? PL/SQL 不会神奇地显示 SELECT 语句的结果。您需要处理结果并显示它,例如使用dbms_output。或者将其设为表函数并直接返回选择的结果。但我同意 ammoQ:临时表的使用似乎相当可疑。 @ammoQ,实际上我必须使用临时表执行此任务以支持一些旧代码。但我很想知道为什么(执行立即'Select * from temp_1';)不产生任何结果。 感谢@a_horse_with_no_name,@ammoQ 的建议。您能否帮我了解 GTT 的替代概念。我的要求是:我在一个视图中有 1000 万条记录。我必须提取视图结果,执行一些业务逻辑,例如执行映射,然后插入到最终表中。插入仍然需要额外的数据逻辑。请提出建议。 您的最新评论是您在此处发布的问题:***.com/questions/35898642/… - 所以最好在此处添加任何其他建议作为答案。 【参考方案1】:

但我很想知道为什么 (execute immediate 'Select * from temp_1';) 没有产生任何结果

有两个原因。首先是因为@a_horse_with_no_name 说PL/SQL 不会显示查询结果。但更重要的是,也许查询从未真正执行过。这种行为是stated in the documentation:

如果 dynamic_sql_statement 是一个 SELECT 语句,并且您省略了 into_clausebulk_collect_into_clause,那么 *execute_immediate_statement( 永远不会执行。

如果您的实际场景有不止一行,您必须立即执行到变量中,或者更可能是集合中,然后处理该数据 - 在批量情况下迭代集合。

没有真正可靠的方法来显示 PL/SQL 中的任何内容;您可以使用dbms_output,但它比实际输出更适合调试,而且您通常无法保证客户端将被配置为显示您放入缓冲区的任何内容。

这完全是学术性的,因为动态创建和删除 GTT 并不是一个好主意,而且有更好的方法来完成你想要做的任何事情。


您显示的块实际上根本不应该运行;当您动态创建 temp_1 时,静态 SQL insert into temp_1 将出错,因为在编译块时该表尚不存在。插入也必须是动态的。任何动态 SQL 都是一个警告信号,您可能做错了什么,尽管有时这是必要的;必须动态地做每件事表明整个方法需要重新考虑,就像在运行时创建对象一样。

【讨论】:

以上是关于PLSQL:在存储过程中使用动态查询时不显示输出的主要内容,如果未能解决你的问题,请参考以下文章

在PLSQL中,存储过程的输出参数最大支持多大

PLSQL 工具怎样调用存储过程咧?

如何在plsql中执行存储过程

PLSQL 表备注,存储过程里的中文都显示乱码,请问怎么处理?

datagrips 存储过程DBMS_OUTPUT.PUT_LINE输出问题

plsql