我有一个奇怪的问题,似乎非常特定于存储过程中的 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循环如何工作所预期的行为,或者这是否是某种类型的错误。
答案 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
即可解决错误;显然,该程序没有权限访问它试图选择的表。奇怪的是,尝试运行程序时没有产生错误;它只是没有产生任何输出。