PL / SQL Вставка 1 строки для каждого результата в выбранном

17

Я пишу процедуру PL / SQL, которая выполняет выбор на основе входных переменных, а затем вставляет строку для каждого результата в select. У меня возникли проблемы с отладкой, что не так с моим запросом из-за моей новизны в PL / SQL. Я знаю, что это должно быть легко, но я почему-то застрял здесь. Спасибо за вашу помощь!

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 Developer Compiler ... «NAME_ID» является недопустимым идентификатором. Я попытался положить его в кавычки, но не кубики. Он также жалуется, что использование «REC» переменных индекса цикла недействительно. Любая помощь очень ценится.

    
задан Craig 29.03.2012 в 16:06
источник

1 ответ

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;
    
ответ дан Tony Andrews 29.03.2012 в 16:13
источник