0

何よりもまず、これは課題のためであるため、あなたが提案したいと思う非常に優れた事前作成済み関数のほとんどは、使用を許可されません。

すべてにフィールドがあるいくつかのテーブルがあります

creation_date
created_by
last_update_date
last_updated_by

作成または更新のためにこれらを埋めるトリガーを作成する必要があります。問題は、これらのテーブルに問題のある null 値があることです。例:

CREATE TABLE parts
(
pno                NUMBER,
pname              VARCHAR2(50) NOT NULL,
qoh                NUMBER       NOT NULL,
price              NUMBER(5,2),
reorder_level      NUMBER(2),
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 parts_PK PRIMARY KEY (pno))

これらの NOT NULL は私に与えられたもので、変更することはできません。だから私はこれを概念化するのに苦労しています。

  • フィールドが作成される前にトリガーがこれらの値を追加する場合、これらのフィールドは NULL ではないため、これらのフィールドを空白にして INSERT INTO を実行することはできません。
  • フィールドの作成後にトリガーがこれらの値を追加すると、コンパイル エラー ORA-00903 および 00922 が発生します。無効なテーブル名と無効なオプションです。

私のトリガーは次のようになると思っていました

CREATE OR REPLACE TRIGGER pcreate
  BEFORE UPDATE on parts
  FOR EACH ROW
BEGIN
  UPDATE
    SET creation_date = SYSDATE;
    SET created_by = USER;
    SET last_update_date = SYSDATE;
    SET last_updated_by = USER;
END;
/

CREATE OR REPLACE TRIGGER pchange
  BEFORE UPDATE on parts
  FOR EACH ROW
BEGIN
  UPDATE
    SET last_update_date = SYSDATE;
    SET last_updated_by = USER;
END;
/
repeat for the other tables

UPSERT の使用が許可されている可能性がありますが、それがどのように機能するかはよくわかりません。提案は大歓迎です。私は本当に学ぶためにこれに参加しているので、他のアドバイスをいただければ幸いです。

編集:

トリガーを認識しない私のパッケージは次のとおりです。パッケージ内でトリガーを呼び出す必要がありますか?

CREATE OR REPLACE PACKAGE process_orders 
AS
  PROCEDURE add_order (p_cno IN NUMBER, p_eno IN NUMBER, p_received IN DATE);
  PROCEDURE add_order_details (p_ono IN NUMBER, p_pno IN NUMBER, p_qty IN NUMBER);
  PROCEDURE ship_order (p_ono IN NUMBER, p_sdate IN DATE);
  PROCEDURE delete_order (p_ono IN NUMBER);
  FUNCTION total_emp_sales (f_eno IN NUMBER) RETURN NUMBER;
END process_orders;
/

CREATE OR REPLACE PACKAGE BODY process_orders 
AS
  PROCEDURE add_order (p_cno IN NUMBER, p_eno IN NUMBER, p_received IN DATE) 
  IS
  ao_emsg       VARCHAR2(100);
  p_rec_today   DATE;
  BEGIN
    SELECT SYSDATE INTO p_rec_today FROM dual;
    IF p_received is null THEN
        INSERT INTO orders (ono, cno, eno, received)
        VALUES(order_number_seq.NEXTVAL,p_cno,p_eno,p_rec_today);
    ELSE
        INSERT INTO orders (ono, cno, eno, received)
    VALUES(order_number_seq.NEXTVAL,p_cno,p_eno,p_received);
    END IF;

  EXCEPTION
    WHEN OTHERS THEN
      ao_emsg := substr(SQLERRM,1,100);
      INSERT INTO orders_errors (ono,transaction_date,message)
      VALUES(order_number_seq.CURRVAL,SYSDATE,ao_emsg);
  END;
  --Etc. Procedures
END;
/
4

2 に答える 2

5

:newトリガーでは、単にレコードを変更したいだけです。あなたのトリガーは次のようになります

CREATE OR REPLACE TRIGGER parts_before_insert
  BEFORE INSERT on parts
  FOR EACH ROW
BEGIN
  :new.creation_date := SYSDATE;
  :new.created_by := USER;
  :new.last_update_date := SYSDATE;
  :new.last_updated_by := USER;
END;

CREATE OR REPLACE TRIGGER parts_before_update
  BEFORE UPDATE on parts
  FOR EACH ROW
BEGIN
  :new.last_update_date := SYSDATE;
  :new.last_updated_by := USER;
END;

ステートメントでは、INSERTこれら 4 つの列を省略し、トリガーに値を入力させます。たとえば(明らかに、主キーはハードコードされているのではなく、シーケンスのようなものから取得されます)

SQL>  insert into parts( pno, pname, qoh, price, reorder_level )
  2     values( 1, 'Widget', 10, 100, 75 );

1 row created.

SQL> select *
  2    from parts;

       PNO PNAME                                                     QOH
---------- -------------------------------------------------- ----------
     PRICE REORDER_LEVEL CREATION_ CREATED_BY LAST_UPDA LAST_UPDAT
---------- ------------- --------- ---------- --------- ----------
         1 Widget                                                     10
       100            75 26-SEP-12 SCOTT      26-SEP-12 SCOTT
于 2012-09-26T17:06:09.403 に答える
3

UPDATEあなたの場合、トリガーでステートメントを実行する必要はありません。を使用して列に新しい値を割り当てるだけ:newです。

CREATE OR REPLACE TRIGGER pchange
  BEFORE UPDATE on parts
  FOR EACH ROW
BEGIN
  :new.last_update_date = SYSDATE;
  :new.last_updated_by = USER;
END;
于 2012-09-26T17:05:24.147 に答える