对于PL / SQL中的循环和列

时间:2011-10-26 10:48:20

标签: 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;

我创建了一个游标。如您所见,我想检查列号为column_1到column_102的所有列。不幸的是||运营商不适用于这种情况。 你知道我的问题的一些解决方案吗?

1 个答案:

答案 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;