我是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;
我创建了一个游标。如您所见,我想检查列号为column_1到column_102的所有列。不幸的是||运营商不适用于这种情况。 你知道我的问题的一些解决方案吗?
答案 0 :(得分:5)
您可以使用dynamic 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;
或者您也可以将rec.column.' || nr ||' is null
分配给变量并在PUT_LINE
部分之外设置EXECUTE IMMEDIATE
:
更新:似乎无法绑定BOOLEAN
个变量,因此我修改了示例以使用NUMBER
。
更新2:可能会提高效率,但在这种情况下可能不合适。对动态SQL使用常量VARCHAR
,并使用绑定变量传入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;
更新3 : 看到了:
无法在动态SQL语句中访问rec
,因为它未定义(超出范围),
似乎无法将非sql类型作为参数传递给动态语句(记录,游标)
一种可能的解决方法是将一些id列(SQL Type)绑定到动态语句,并使用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;