为什么这个PL / SQL过程不起作用?

时间:2011-12-16 17:39:06

标签: sql oracle stored-procedures plsql toad

我有一个光标,它返回两个值:一个我将使用(因此将分配给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),但无效。然后我用Google搜索了一下,看到我应先TO_CHAR()我的var然后输出它。也没用。

2 个答案:

答案 0 :(得分:2)

将号码传递给DBMS_OUTPUT.PUT_LINE没有问题。 Oracle将使用默认格式将其他内置类型静默转换为VARCHAR2。如果你想控制使用的格式,你只需要使用TO_CHAR - 这通常是一个好主意,但通常不是必需的。

但是,有一种可能性是您没有看到输出,因为您尚未启用它。如果您在SQLPlus中运行测试,请确保在运行包含DBMS_OUTPUT调用的代码之前SET SERVEROUTPUT ON。如果您正在使用其他客户端,请查阅其文档以了解启用DBMS_OUTPUT的正确方法。 (当然,您可以通过添加另一个调用来输出字符串文字来测试它是否已启用。)

用于填充out参数的技术没有任何内在错误。但是,没有必要从游标返回两列;您的select *可能只是select CODSDP。您似乎误解了谓词中引用的任何列必须位于选择列表中,但事实并非如此。在最里面的查询中,选择列表不需要包含NRONIPCODTIPOMOV,因为它们未在外部块中引用;该查询中的WHERE子句可以引用表中的任何列,无论它是否在选择列表中。

所以,我的第一个猜测是你根本没有启用服务器输出。我现在能想到的唯一另一种可能性是你在两个不同的会话中运行你的查询和过程,其中一个会对表有未提交的事务,所以他们实际上看到了不同的数据。

如果这些建议似乎不是问题,我建议您在单个SQLPlus会话中运行独立查询和过程的测试,然后在此复制并粘贴整个会话,这样我们就可以看到你正在做什么。

答案 1 :(得分:0)

对不起,当答案与我正在使用的工具有关时,我已经让你们花时间回答我。我希望你们所有人都学到了一些东西。

该查询至少对我有用,我没有遇到任何不起作用的边缘情况,但我没有详尽地测试它。

问题 TOAD ,我用来运行程序的工具,有时用我告诉它的参数填充程序,但有时它不会吨。这里的问题是我试图在没有参数的情况下执行该过程,结果没有结果......

经验教训:使用右键单击>运行程序时,仔细检查生成的过程代码。在TOAD版本9上运行过程。