2012-03-29 13 views
17

Tôi viết một thủ tục PL/SQL mà thực hiện một lựa chọn dựa trên các biến đầu vào và sau đó chèn một hàng cho mỗi kết quả trong các lựa chọn. Tôi gặp rắc rối gỡ lỗi những gì là sai với truy vấn của tôi do sự mới mẻ của tôi để PL/SQL. Tôi biết điều này phải dễ dàng, nhưng tôi bị kẹt ở đây vì một lý do nào đó. Cảm ơn bạn đã giúp đỡ!PL/SQL Chèn 1 hàng cho mỗi kết quả trong một lựa chọ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; 

Theo trình biên dịch nhà phát triển Oracle ... 'NAME_ID' là số nhận dạng không hợp lệ. Tôi đã thử đặt nó trong dấu ngoặc kép nhưng không có súc sắc. Nó cũng phàn nàn rằng các biến chỉ số vòng lặp 'REC' sử dụng không hợp lệ. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.

Trả lời

42

Không cần cho SQL động ở đây:

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; 

Vẫn còn tốt hơn bạn có thể tránh một hàng-by-hàng tiếp cận con trỏ chậm như thế này:

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

Nếu bạn thực sự đã làm cần SQL động bạn không nên ghép các giá trị vào nó, nhưng sử dụng các biến liên kết:

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;