mat*_*yyy 3 sql database oracle plsql
我是PL/SQL的新手.我在这种语言中遇到循环问题.我想像这样循环:
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
IF rec.column_||nr IS NULL
THEN
DBMS_OUTPUT.PUT_LINE('test');
END IF;
END LOOP;
Run Code Online (Sandbox Code Playgroud)
我创建了一个游标.如您所见,我想检查列号为column_1到column_102的所有列.不幸的是|| 运营商不适用于这种情况.你知道我的问题的一些解决方案吗?
您可以使用动态PL/SQL执行此操作.使用EXECUTE IMMEDIATE语句将字符串参数作为PL/SQL执行,您可以||按照问题中的意图进行弥补.
例:
BEGIN
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'BEGIN ' ||
'IF rec.column.' || nr ||' is null THEN ' ||
'DBMS_OUTPUT.PUT_LINE(''test''); ' ||
'END IF; ' ||
'END; ';
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
或者您也可以分配rec.column.' || nr ||' is null给变量并使PUT_LINE外部成为EXECUTE IMMEDIATE零件:
更新:似乎无法绑定BOOLEAN变量,所以我修改了示例以使用a NUMBER.
更新2:可能的效率提高,尽管可能不适合这种情况.VARCHAR对动态SQL 使用常量,并nr使用绑定变量传入.如果在大型循环中,这比使用本机SQL更有效.不过,我认为'rec.column.:arg is null不会执行'rec.column.1 is null.
DECLARE
isnull NUMBER;
BEGIN
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'BEGIN ' ||
'IF rec.column.' || nr ||' IS NULL THEN ' ||
':x:=1; ' ||
'ELSE ' ||
':x:=0; ' ||
'END IF; ' ||
'END; '
USING OUT isnull;
IF isnull = 1 THEN
DBMS_OUTPUT.PUT_LINE('test');
END IF;
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
更新3:看到:
无法访问rec动态SQL语句内部,因为它未定义(超出范围),
似乎不可能将非sql类型作为参数传递给动态语句(记录,游标)
一种可能的解决方法是将一些id列(SQL Type)绑定到dynamic语句,并使用select子句来查找当前列是否为null:
DECLARE
isnull NUMBER;
rec_id NUMBER; -- Identifier of the fetched record
BEGIN
rec_id := rec.id;
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'SELECT 1 FROM my_table WHERE id = :idarg ' ||
' AND column_' || nr || ' IS NULL'
INTO isnull USING rec_id;
IF isnull = 1 THEN
DBMS_OUTPUT.PUT_LINE('test');
END IF;
END LOOP;
END;Run Code Online (Sandbox Code Playgroud)