How to Duplicate multiple rows (Oracle)
cursor, oracle, plsql
Solution
Why do you need a cursor? You can do this with SQL directly:
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;
Anyway, the actual problem is that your `ID` is a `VARCHAR2(4)`, whereas you think it is a `NUMBER`. You actually do not have an employee with `ID = 5`, but you do have one with `ID = '05'`. So without changing anything, your procedure already works:
BEGIN
employeepackage.duplicateemployee('05');
END;
Of course, it would make sense to change the data type of `ID`.
Problem
I'm trying to make a Procedure that will duplicate multiple rows of a table (or only one single row) and incrementing the ID for each row insertion. My problem is that inside my procedure I used a cursor to select the rows to duplicate, when i select all rows without WHERE condition in that cursor everything works fine. But when i set a WHERE condition to select only one row... nothing happens Here is my procedure ``` 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; ``` I know in this example having a procedure selecting a primary key to duplicate is pointless but in my production base it will be used to select a Foreign key. Bellow is the code require to create a the test table and SEQUENCE I used for this procedure ``` 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'); ``` Here for the Sequence that will manage Primary key (ID) ``` CREATE SEQUENCE "TEST"."EMPLOYEE_SEQ" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE ORDER NOCYCLE ; ``` And here the code to execute the procedure ``` BEGIN employeepackage.duplicateemployee(5); END; ``` I really don't understand why it doesn't properly work for a single row when it's working to plicate all rows ? It there a limitation for cursors having less than 2 rows ? Any help would be much appreciated ;)