Helpex - Trao đổi & giúp đỡ Đăng nhập
3

Tôi đang cố tạo một Thủ tục sẽ sao chép nhiều hàng của bảng (hoặc chỉ một hàng duy nhất) và tăng ID cho mỗi lần chèn hàng.

Vấn đề của tôi là bên trong thủ tục của tôi, tôi đã sử dụng con trỏ để chọn các hàng để sao chép, khi tôi chọn tất cả các hàng mà không có điều kiện WHERE trong con trỏ đó, mọi thứ hoạt động tốt. Nhưng khi tôi đặt điều kiện WHERE để chỉ chọn một hàng ... không có gì xảy ra

Đây là thủ tục của tôi

CREATE OR REPLACE PROCEDURE DuplicateEmployee (p_EmployeeID IN Employee.id%TYPE)
 AS
  p_New_EmployeeID Employee.id%TYPE;
  CURSOR c_DuplicateEmployee IS
    SELECT *
        FROM Employee
        WHERE Employee.id = p_EmployeeID; -- if this line is deleted all content is duplicated
  row_Employee c_DuplicateEmployee%ROWTYPE;
    BEGIN
      FOR myEmployee IN c_DuplicateEmployee LOOP
          p_New_EmployeeID := employee_seq.NEXTVAL;
          INSERT INTO Employee(id, first_name, last_name, start_date, end_date, salary, city, description)
            VALUES(p_New_EmployeeID, myEmployee.first_name, myEmployee.last_name, myEmployee.start_date, myEmployee.end_date, myEmployee.salary, myEmployee.city, myEmployee.description);
      END LOOP;
    COMMIT;
   END DuplicateEmployee;

Tôi biết trong ví dụ này có một thủ tục chọn khóa chính để sao chép là vô nghĩa nhưng trong cơ sở sản xuất của tôi, nó sẽ được sử dụng để chọn khóa Ngoại.

Dưới đây là mã yêu cầu để tạo bảng kiểm tra và SEQUENCE tôi đã sử dụng cho quy trình này

CREATE TABLE Employee
  (
    ID         VARCHAR2(4 BYTE) NOT NULL,
    First_Name VARCHAR2(10 BYTE),
    Last_Name  VARCHAR2(10 BYTE),
    Start_Date DATE,
    End_Date DATE,
    Salary      NUMBER(8,2),
    City        VARCHAR2(10 BYTE),
    Description VARCHAR2(15 BYTE)
  );
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('01', 'Jason', 'Martin', to_date('19960725','YYYYMMDD'), to_date('20060725','YYYYMMDD'), 1234.56, 'Toronto', 'Programmer');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('02', 'Alison', 'Mathews', to_date('19760321','YYYYMMDD'), to_date('19860221','YYYYMMDD'), 6661.78, 'Vancouver', 'Tester');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('03', 'James', 'Smith', to_date('19781212','YYYYMMDD'), to_date('19900315','YYYYMMDD'), 6544.78, 'Vancouver', 'Tester');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('04', 'Celia', 'Rice', to_date('19821024','YYYYMMDD'), to_date('19990421','YYYYMMDD'), 2344.78, 'Vancouver', 'Manager');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('05', 'Robert', 'Black', to_date('19840115','YYYYMMDD'), to_date('19980808','YYYYMMDD'), 2334.78, 'Vancouver', 'Tester');
 INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
  VALUES
    ('06', 'Linda', 'Green', to_date('19870730','YYYYMMDD'), to_date('19960104','YYYYMMDD'), 4322.78, 'New York', 'Tester');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
VALUES
    ('07', 'David', 'Larry', to_date('19901231','YYYYMMDD'), to_date('19980212','YYYYMMDD'), 7897.78, 'New York', 'Manager');
INSERT
INTO Employee
    (ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
VALUES
    ('08', 'James', 'Cat', to_date('19960917','YYYYMMDD'), to_date('20020415','YYYYMMDD'), 1232.78, 'Vancouver', 'Tester');

Tại đây cho Trình tự sẽ quản lý Khóa chính (ID)

CREATE SEQUENCE "TEST"."EMPLOYEE_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE ;

Và đây là mã để thực hiện thủ tục

BEGIN
  employeepackage.duplicateemployee(5);
END;

Tôi thực sự không hiểu tại sao nó không hoạt động chính xác cho một hàng khi nó hoạt động để phân loại tất cả các hàng? Nó có một hạn chế cho con trỏ có ít hơn 2 hàng?

Bất kì sự trợ giúp nào đều được đánh giá cao ;)

3 hữu ích 0 bình luận 6.8k xem chia sẻ
7

Tại sao bạn cần một con trỏ? Bạn có thể làm điều này trực tiếp với SQL:

INSERT INTO Employee(id, first_name, last_name, 
                     start_date, end_date, 
                     salary, city, description)
SELECT employee_seq.NEXTVAL, e.first_name, e.last_name,
       e.start_date, e.end_date, 
       e.salary, e.city, e.description
FROM Employee e
WHERE e.id = p_EmployeeID;

Dù sao, vấn đề thực tế là của bạn IDlà a VARCHAR2(4), trong khi bạn nghĩ nó là a NUMBER. Bạn thực sự không có nhân viên với ID = 5, nhưng bạn có một nhân viên với ID = '05'. Vì vậy, không cần thay đổi bất cứ điều gì, thủ tục của bạn đã hoạt động:

BEGIN
  employeepackage.duplicateemployee('05');
END;

Tất nhiên, sẽ có ý nghĩa nếu thay đổi kiểu dữ liệu của ID.

7 hữu ích 3 bình luận chia sẻ
0

Giải pháp từ Lukas nếu tốt cho bảng đầu tiên và bảng cuối cùng của tôi mà sẽ không cần gọi người khác THỦ TỤC để sao chép nhiều con, mặc dù đối với bảng trung gian tôi đã sử dụng:

PROCEDURE Duplicate_Company (p_IdCity IN City.IdCity%TYPE) AS
p_New_IdCompany Company.IdCompany%TYPE;
CURSOR c_DuplicateCompany IS
SELECT *
    FROM Company c
    WHERE c.IdCity = p_IdCity; 
row_Company c_DuplicateCompany%ROWTYPE;
BEGIN
  FOR c1 IN c_DuplicateCompany LOOP
      p_New_IdCompany := company_seq.NEXTVAL;
      INSERT INTO Company(IdCompany, IdCity, Name, CreationDate)
        VALUES(p_New_IdCompany, c1.IdCity, c1.Name, c1.CreationDate);
      -- Call the procedure to duplicate current employee
      Duplicate_Employee(c1.IdCompany);
  END LOOP;
END Duplicate_Company;

Nó có phải là một cách tiếp cận tốt?

0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ oracle plsql cursor , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading