2012-03-29 107 views
17

我正在編寫一個PL/SQL過程,該過程根據輸入變量執行選擇,然後爲select中的每個結果插入一行。由於我對PL/SQL的新穎性,我無法調試我的查詢出了什麼問題。我知道這一定很容易,但由於某種原因,我被困在這裏。謝謝你的幫助!PL/SQL爲選擇中的每個結果插入1行

CREATE OR REPLACE PROCEDURE setup_name_map(ranking_id IN NUMBER, class_string IN VARCHAR2) 
IS 
BEGIN 

    FOR rec IN (SELECT NAME_ID FROM PRODUCT_NAMES WHERE NAME = class_string) 
    LOOP 
     EXECUTE IMMEDIATE 'INSERT INTO NAME_RANKING (NAME_ID, RANKING_ID) VALUES (' || rec.NAME_ID || ', ' || ranking_id || ')'; 
    END LOOP; 
END; 

根據Oracle開發人員編譯器...'NAME_ID'是一個無效的標識符。我試圖把它放在引號中,但沒有骰子。它也抱怨循環索引變量'REC'的使用是無效的。任何幫助深表感謝。

回答

42

沒有必要對動態SQL這裏:

BEGIN 

    FOR rec IN (SELECT NAME_ID FROM PRODUCT_NAMES 
       WHERE NAME = class_string) 
    LOOP 
     INSERT INTO NAME_RANKING (NAME_ID, RANKING_ID) 
     VALUES (rec.NAME_ID, ranking_id); 
    END LOOP; 
END; 

更妙的是你能避免這樣的慢行通過行光標的方法:

BEGIN 
    INSERT INTO NAME_RANKING (NAME_ID, RANKING_ID) 
    SELECT NAME_ID, ranking_id FROM PRODUCT_NAMES 
    WHERE NAME = class_string; 
END; 

如果你確實需要的動態SQL,您不應該將值連接到它,但使用綁定變量:

BEGIN 

    FOR rec IN (SELECT NAME_ID FROM PRODUCT_NAMES 
       WHERE NAME = class_string) 
    LOOP 
     EXECUTE IMMEDIATE 'INSERT INTO NAME_RANKING 
          (NAME_ID, RANKING_ID) VALUES (:b1, :b2) 
     USING rec.NAME_ID, ranking_id; 
    END LOOP; 
END;