2011-10-26 29 views
3

我是PL/SQL中的新成員。我在使用這種語言的循環中遇到問題。我想這樣做循環:For循環和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的所有列。不幸的是||運營商不適合這種情況。 你知道我的問題的一些解決方案嗎?

回答

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一個變量,使EXECUTE IMMEDIATE部分外PUT_LINE

UPDATE:現在看來,這是不可能的綁定BOOLEAN變量,所以我修改了示例以使用NUMBER

UPDATE 2:有一個可能的效率提高,儘管可能不適合在這種情況下。爲動態SQL使用常量VARCHAR,並在nr中傳遞綁定變量。如果在大循環中,這比使用本機SQL更有效。不過,我認爲'rec.column.:arg 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: 眼看:

  • 這是不可能的訪問rec動態SQL語句中,因爲它是不確定的(超出範圍),

  • 似乎不可能將非sql類型作爲參數傳遞給動態語句(r的eCord,光標)

可能的解決方法是將一些ID列(SQL類型)綁定到動態語句,並使用select條款,以找出是否當前列是空:

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;
+0

你能舉個例子嗎? – matyyyy

+0

不幸的是,BOOLEAN不是sql類型的,因此我得到一個錯誤。 – matyyyy

+0

是的,你說的對,就像[這裏]解釋的一樣(http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/dynamic.htm#BHCEJIDC)。我在測試它的時候就明白了這一點。我已經更新了這個例子來代替使用'NUMBER'。 –