Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.misc -> Re: Conditional Trigger

Re: Conditional Trigger

From: <fitzjarrell_at_cox.net>
Date: Tue, 20 Nov 2007 06:36:46 -0800 (PST)
Message-ID: <7f2f2b40-cefe-4b3e-bc2d-11376b5c0339@b15g2000hsa.googlegroups.com>


Comments embedded.
On Nov 20, 6:14 am, mowi..._at_hotmail.com wrote:
> Hello all,
>
> I have the following task: I have a table with two fields, ISBN
> (NUMBER 9), TITLE and PERIODICAL_OWNER (NUMBER 9).

Appears to be three columns to me.

> I am trying to
> create a trigger that checks on insert, that the ISBN being entered is
> not already in the table but if it does, it must exist in the
> PERIODICAL_OWNER column.

Why use a trigger, unless this is a classroom assignment? A trigger won't capture any 'violations' in a set of inserts in a single transaction, thus you could have duplicate records inserted when initially populating this table and the trigger won't 'see' the 'error' and happily allow the duplicates to exist:

SQL> set echo off

Table created.

Trigger created.

No errors.
SQL>
SQL> insert all
  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', null)   6 into periodical
  7 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   8 select *
  9 from dual;

3 rows created. -- Note the first and third records inserted are the same which SHOULD be an error but is not as the trigger didn't catch it

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> insert all
  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', null)   6 into periodical
  7 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   8 select *
  9 from dual;
into periodical

     *
ERROR at line 2:
ORA-21000: error number argument to raise_application_error of -1422 is out of
range
ORA-06512: at "BING.VAL_ISBN", line 28
ORA-04088: error during execution of trigger 'BING.VAL_ISBN' -- This is basically a 'single-row subquery returns more than one row' error because of the situation described above

SQL> I intentionally did not show the trigger code since this is apparently an assignment you need to complete. Some hints to help you:

*) If there are no rows in the table there is nothing to check. *) :new and :old reference the current record, not all records in the table
*) You'll need to select the isbn from the table where it matches :new.isbn
*) For existing isbn values you'll need to compare :new.periodical_owner to :new.isbn *) You'll need to handle the situation where periodical_owner is NULL *) This will need to use the autonomous_transaction pragma unless you write a function

    to return the existing isbn and call that from your trigger

For the uninitiated this is not a simple trigger to write.

Ridding ourselves of the duplicate record for the initial load:

SQL> set echo off serveroutput on size 1000000

Table created.

Trigger created.

No errors.

SQL>
SQL> -- Initial load
SQL> insert all

  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', null)   6 select * from dual;

2 rows created.

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> -- Set of 'bad' insert attempts
SQL> insert all

  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', null)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', null)   6 select * from dual;
into periodical

     *
ERROR at line 2:
ORA-20070: Existing ISBN and PERIODICAL_OWNER must be equal for existing ISBN
values
ORA-06512: at "BING.VAL_ISBN", line 26
ORA-04088: error during execution of trigger 'BING.VAL_ISBN'

SQL>
SQL> insert all
  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', 4443215678)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', 9876543210)
  6 select * from dual;
into periodical

     *
ERROR at line 2:
ORA-20070: Existing ISBN and PERIODICAL_OWNER must be equal for existing ISBN
values
ORA-06512: at "BING.VAL_ISBN", line 26
ORA-04088: error during execution of trigger 'BING.VAL_ISBN'

SQL>
SQL> -- Set of 'good' inserts
SQL> insert all

  2 into periodical
  3 values (1590596366, 'Cost-Based Oracle Fundamentals', 1590596366)   4 into periodical
  5 values (1590595300, 'Expert Oracle Database Architecture', 1590595300)
  6 select * from dual;

2 rows created.

SQL> So it works, sort of.

>
> So, if the new ISBN being entered is already in the table, it has to
> be in the PERIODICAL_OWNER column in order for it to be accepted. I am
> new to PL/SQL and have tried writing a trigger but it's not working.
> Here it is:
>
> IF :New.ISSN = :Old.ISSN And

That condition checks for an update to an existing record, it doesn't check the prospective insert against other records in the table. You'll need a select statement for that.

> :New.ISSN NOT IN (:Old.Tidsskriftnr_eier) THEN
> RAISE_APPLICATION_ERROR(-20070, 'ERROR>>' ||
> ' PERIODICAL:' ||
> ' For ISSN that already exists in the basen, it' ||
> ' must exist in periodicald to be accepted.');
> ELSE
> :New.ISSN := :New.ISSN;
> END IF;
>

Obviously there is more to this 'specification' than you've cared to share in your 'problem' description. Either provide all of the required information or expect less than useful help.

> Thank you in advance for your help
>
> --
> Me

David Fitzjarrell Received on Tue Nov 20 2007 - 08:36:46 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US