2012-03-29 69 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;