为啥这个 PL/SQL 过程不起作用?
Posted
技术标签:
【中文标题】为啥这个 PL/SQL 过程不起作用?【英文标题】:Why doesn't this PL/SQL procedure work?为什么这个 PL/SQL 过程不起作用? 【发布时间】:2011-12-16 17:39:06 【问题描述】:我有一个游标,它返回两个值:一个是我将使用的(因此将分配给一个 out
变量),另一个是我只返回以使 ROWNUM 工作正常的。
如果我将游标作为查询运行,它会按预期工作。但是,如果我执行该过程,out
变量就会为空。我的方法不支持吗?我的意思是,返回两个值但只使用其中一个?
这是我的程序代码:(不要过多研究查询本身。它有效,我知道它有点难看,但它有效。这是我发现返回倒数第二个的唯一方法行)
procedure retorna_infos_tabela_164(i_nip in varchar,
o_CODSDPANTERIOR out number) is
cursor c_tabela_164 is
select *
from(
select CODSDP,ROWNUM rn
from
(
select NRONIP,CODTIPOMOV,CODSDP
from TB164_HISTORICOMOVIMENTACOES
where NRONIP = i_nip and
CODTIPOMOV='S1'
order by DTHMOV desc
)
)
where rn=2;
v_temp_nr number;
begin
open c_tabela_164;
fetch c_tabela_164 into o_CODSDPANTERIOR,v_temp_nr;
close c_tabela_164;
end retorna_infos_tabela_164;
编辑我尝试运行此过程的方式是dbms_output.put_line(o_CODSDPANTERIOR)
,但它不起作用。然后我用谷歌搜索了一下,发现我应该先TO_CHAR()
我的变量,然后再输出。也没有用。
【问题讨论】:
是否可以将游标作为查询运行? (在 sybase 中不是) @aF 把select
关键字前面的部分剪掉就可以运行了。 :)
我认为游标是查询。你可以在 sql runner 中按 ctrl+c 然后按 ctrl+v。
【参考方案1】:
将数字传递给DBMS_OUTPUT.PUT_LINE
没有问题。 Oracle 将使用默认格式静默地将其他内置类型转换为VARCHAR2
。如果你想控制使用的格式,你只需要使用TO_CHAR
——这通常是个好主意,但通常不是必需的。
但是,一种可能性是您没有看到输出,因为您没有启用它。如果您在 SQLPlus 中运行测试,请确保在运行包含 DBMS_OUTPUT 调用的代码之前SET SERVEROUTPUT ON
。如果您正在使用其他客户端,请查阅其文档以了解启用 DBMS_OUTPUT 的正确方法。 (您当然可以通过添加另一个调用来输出字符串文字来测试它是否已启用。)
您用来填充 out 参数的技术本身并没有错。但是,没有必要从游标返回两列;你的select *
可能只是select CODSDP
。您似乎误以为谓词中引用的任何列都必须在选择列表中,但事实并非如此。在最里面的查询中,选择列表不需要包含NRONIP
或CODTIPOMOV
,因为它们没有在外部块中引用;该查询中的 WHERE 子句可以引用表中的任何列,无论它是否在选择列表中。
所以,我的第一个猜测是您根本没有启用服务器输出。我现在唯一能想到的另一种可能性是您在两个不同的会话中运行查询和过程,其中一个对表有未提交的事务,因此他们实际上看到的数据不同。
如果这些建议似乎不是问题,我建议您在单个 SQLPlus 会话中运行独立查询和过程的测试,然后将整个会话复制并粘贴到此处,以便我们可以准确查看你在做什么。
【讨论】:
【参考方案2】:很抱歉,当答案与我正在使用的工具有关时,我让你们花时间回答我。我希望你们都学到了一些东西。
该查询至少对我有用,我没有遇到任何它不起作用的边缘情况,但我没有对它进行详尽的测试。
问题是 TOAD,我用来运行程序的工具,有时会使用我告诉它的参数填充程序,但有时它不会吨。这里的问题是我试图在没有参数的情况下执行该过程,但没有产生任何结果......
经验教训:在 TOAD 版本 9 上使用右键单击 > 运行过程来运行过程时仔细检查生成的过程代码。
【讨论】:
也许是另一堂课——当您的 GUI 工具出现意外结果时,请切换到 SQLPlus 之类的准系统工具以上是关于为啥这个 PL/SQL 过程不起作用?的主要内容,如果未能解决你的问题,请参考以下文章