-1

潜在的な空の「受信」フィールドに現在の日付を使用させる手順を作成しようとしています。Order_number_seq注文番号列に入力するというシーケンスを作成しました(Ono)。注文テーブルのエラーをテーブルのエントリにリンクする方法がわかりませんOrders_errors

これは私がこれまでに持っているものです:

CREATE PROCEDURE Add_Order
  AS BEGIN
    UPDATE Orders
    CREATE Sequence Order_number_seq
    Start with 1,        
    Increment by 1;
    UPDATE Orders SET  received = GETDATE WHERE received = null;

これらは私が使用しているテーブルです:

注文表

(
 Ono Number Not Null,
 Cno Number Not Null,
 Eno  Number Not Null,
 Received Date Null,
 Shipped_Date Date Null,
 Creation_Date  Date Not Null,
 Created_By  VARCHAR2(10) Not Null,
 Last_Update_Date Date Not Null,
 Last_Updated_By VARCHAR2(10) Not Null,
 CONSTRAINT Ono_PK PRIMARY KEY (Ono), 
 CONSTRAINT Cno_FK FOREIGN KEY (Cno)
 REFERENCES Customers_Proj2 (Cno)
);

Order_Errors テーブル

(
 Ono Number Not Null,
 Transaction_Date Date Not Null,
 Message  VARCHAR(100) Not Null
);

特に注文テーブルのエラーをリンクしてテーブルに新しいエントリを作成する際に、どんな助けでも大歓迎OrderErrorsです。

前もって感謝します。

4

2 に答える 2

2

Martin Drautzburg の回答とは対照的に、Order_Errorsテーブルには注文番号の外部キーはありません。その目的を果たしているように見える列がありOnoますが、Oracle に関する限り、それは異質なものではありません。Cno_FKこれを外部キーにするには、 onのような制約を追加する必要がありますOrders。例:

CREATE TABLE Order_Errors
(
 Ono Number Not Null,
 Transaction_Date Date Not Null,
 Message  VARCHAR(100) Not Null,
 CONSTRAINT Order_Errors_Orders_FK FOREIGN KEY (Ono) REFERENCES Orders (Ono)
);

または、Order_Errorsテーブルが既に存在し、それを削除したくない場合は、次のALTER TABLEステートメントを使用できます。

ALTER TABLE Order_Errors
ADD CONSTRAINT Order_Errors_Orders_FK FOREIGN KEY (Ono) REFERENCES Orders (Ono)
;

手順に関しては、あなたがやろうとしていることは、PROCEDURE. 行の挿入時にデフォルト値を使用することを意図している場合は、トリガーがこの目的に適しています。(トリガーを使用するとパフォーマンスが低下するため、考慮してください。)

-- Create sequence to be used
CREATE SEQUENCE Order_Number_Sequence
START WITH 1
INCREMENT BY 1
/

-- Create trigger for insert
CREATE TRIGGER Orders_Insert_Trigger
BEFORE INSERT ON Orders
FOR EACH ROW
DECLARE
BEGIN
  IF :NEW.Ono IS NULL
  THEN
    SELECT Order_Number_Sequence.NEXTVAL INTO :NEW.Ono FROM DUAL;
  END IF;
  IF :NEW.Received IS NULL
  THEN
    SELECT CURRENT_DATE INTO :NEW.O_Received FROM DUAL;
  END IF;
END;
/

このトリガーは、テーブルに挿入されたすべての行に対して実行されOrdersます。Ono列が存在するかどうかを確認し、存在NULLする場合はシーケンスの ID に置き換えます。(後でシーケンスによって生成される ID を提供しないように注意してください。主キーの競合エラーが発生します。)次に、受信した日付が現在の日付であるかどうかを確認し、関数NULLを使用して現在の日付に設定します。 CURRENT_DATE(これはあなたが理解しようとしていたことの 1 つであると私は信じています)、もしそうなら。

(補足: 他のデータベースでは、これを行うためにトリガーを必要とせず、代わりにデフォルト値を使用できる場合があります。たとえば、PostgreSQL では、そのDEFAULT句で関数呼び出しを使用できると思います。これが、そのSERIAL自動インクリメント タイプの実装方法です。 .)

UPDATE単に既存のデータを更新しようとしているだけなら、ステートメントだけで十分だと思います。これが必要な理由はありPROCEDUREますか?

もう1つの注意事項。Order_Errorsには主キーがありません。Onoおそらく、自動インクリメントの代理キー列を用意するか、その列を選択するだけの場合は、少なくともその列にインデックスを作成する必要があります。

于 2013-05-06T02:04:49.363 に答える