2012-03-29 17 views
17

Estoy escribiendo un Procedimiento PL/SQL que realiza una selección basada en variables de entrada y luego inserta una fila para cada resultado en la selección. Tengo problemas para depurar lo que está mal con mi consulta debido a mi novedad en PL/SQL. Sé que esto debe ser fácil, pero estoy atrapado aquí por alguna razón. ¡Gracias por tu ayuda!PL/SQL Insertar 1 fila para cada resultado en una selección

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; 

De acuerdo con el desarrollador de Oracle Compilador ... 'NAME_ID' es un identificador válido. He intentado ponerlo entre comillas pero no dados. También se queja de que el uso de las variables de índice de bucle 'REC' no es válido. Cualquier ayuda es muy apreciada.

Respuesta

42

No hay necesidad de SQL dinámico aquí:

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; 

Mejor aún se puede evitar una aproximación lenta fila por fila del cursor como esta:

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

Si realmente necesitamos el SQL dinámico no debe concatenar valores en él, pero utilizando variables de vinculación:

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; 
Cuestiones relacionadas