dbms_output.put_line不能在存储过程的Cursor For循环中工作

时间:2017-10-31 01:17:33

标签: oracle loops stored-procedures plsql cursor

我有一个奇怪的问题,似乎非常特定于存储过程中的 CURSOR FOR循环。为清楚起见,我在DBeaver中使用Oracle并尝试遍历表中的所有列并打印出select语句的结果。

我无法访问确切的代码,但这是功能上的近似值:

CREATE OR REPLACE PROCEDURE column_null(table_name_in IN VARCHAR2) 
AS
str_query VARCHAR2(1000);
temp_number NUMBER(10);
CURSOR col_cursor IS
SELECT * FROM user_tab_cols 
WHERE table_name = table_name_in;

BEGIN
FOR c_id IN col_cursor
LOOP
  str_query := 'select COUNT(*) FROM ' || table_name_in || 
               ' WHERE ' || c_id.column_name || ' IS NOT NULL';
  EXECUTE IMMEDIATE str_query INTO temp_number;
  DBMS_OUTPUT.PUT_LINE(temp_number);
END LOOP;
END;

现在,奇怪的是,如果我在存储函数之外执行完全相同的代码块(减去额外的DECLARE关键字),它将按预期工作。即使我试着回应一下你好'在循环中它按预期工作,但一旦它成为存储过程就停止工作。我今天已经测试了好几个小时了,我感到非常困惑;作为参考,我最近才熟悉PL / SQL,所以它的谜团让我感到厌烦。

此外,它似乎特定于 CURSOR FOR 循环;如果我用一般的数字循环(即FOR c_id IN 1 .. 10)替换Cursor For循环,程序将产生输出就好了。并且只是DBMS_OUTPUT.PUT_LINE受到了影响; Cursor For循环内部的所有在存储过程中被忽略,包括变量更新,即使它们在正常的PL / SQL块中工作正常。

总结:作为PL / SQL块正常工作,在数字for循环中工作正常,但由于某种原因,存储过程和游标for循环的确切组合不会产生输出;事实上,从我的测试来看,似乎没有任何意义在光标中发生存储函数的循环。

这是一个DBeaver错误吗? PL / SQL奇怪吗?我在这里发帖是因为我不知道这是否是由于过程和/或Cursor For循环如何工作所预期的行为,或者这是否是某种类型的错误。

2 个答案:

答案 0 :(得分:0)

您所做的是宣布程序。既然已经声明了它,你必须使用像bellow这样的程序来调用它。很可能它会产生输出。

选项01

    set serveroutput on;
    Declare
      v_table_name_in IN VARCHAR2(499);

    Begin
      v_table_name_in := 'your table name';
      column_null(table_name_in => v_table_name_in);
    end;  

选项02 获取返回参数。理想情况下,表类型为out参数。在上面的代码中,遍历它并打印值。

选项03。 将输出记录到日志表中。

答案 1 :(得分:0)

我发现只需在程序中添加AUTHID current_user即可解决错误;显然,该程序没有权限访问它试图选择的表。奇怪的是,尝试运行程序时没有产生错误;它只是没有产生任何输出。