3

テーブルの複数の行(または1つの行のみ)を複製し、行を挿入するたびにIDをインクリメントするプロシージャを作成しようとしています。

私の問題は、プロシージャ内でカーソルを使用して複製する行を選択したところ、そのカーソルでWHERE条件なしですべての行を選択すると、すべてが正常に機能することです。しかし、WHERE条件を設定して1つの行のみを選択すると、何も起こりません

これが私の手順です

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;

この例では、複製する主キーを選択する手順があることは無意味ですが、私の本番ベースでは、外部キーを選択するために使用されます。

以下は、この手順で使用したテストテーブルとシーケンスを作成するために必要なコードです。

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');

ここでは、主キー(ID)を管理するシーケンスについて説明します。

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

そしてここに手順を実行するためのコード

BEGIN
  employeepackage.duplicateemployee(5);
END;

すべての行を複製するために機能しているのに、なぜそれが単一の行に対して適切に機能しないのか、私は本当に理解していませんか?2行未満のカーソルには制限がありますか?

どんな助けでも大歓迎です;)

4

2 に答える 2

7

なぜカーソルが必要なのですか?これは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;

とにかく、実際の問題はあなたIDがであるということですが、あなたはVARCHAR2(4)それがであると思いますNUMBER。実際には、の従業員はありませんが、の従業員はID = 5いますID = '05'。したがって、何も変更しなくても、手順はすでに機能しています。

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

もちろん、のデータ型を変更することは理にかなっていますID

于 2012-05-14T14:43:00.533 に答える
0

複数の子を複製するために他のPROCEDUREを呼び出す必要がない、最初と最後のテーブルに問題がない場合のLukasのソリューション。ただし、中間テーブルには次を使用しました。

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;

それは良いアプローチですか?

于 2012-05-15T12:06:25.550 に答える