Re: Database triggers - Mailing list pgsql-sql

From Charles Wilt
Subject Re: Database triggers
Date
Msg-id MPG.1ae85cb4749764d29896d8@news.easynews.com
Whole thread Raw
List pgsql-sql
Do you have access to the SQL Reference Manual:

http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/db2/rbafzmsthctri
gger.htm#HDRHCTRIGGER


There's an example of what you want to do:

CREATE TRIGGER SAL_ADJ
AFTER UPDATE OF SALARY ON EMPLOYEE
REFERENCING OLD AS OLD_EMP           NEW AS NEW_EMP
FOR EACH ROW MODE DB2SQL
WHEN (NEW_EMP.SALARY > (OLD_EMP.SALARY *1.20))
BEGIN ATOMICSIGNAL SQLSTATE ?75001?(?Invalid Salary Increase - Exceeds 20%?);
END

Since you want a before trigger change "AFTER UPDATE" to "BEFORE UPDATE"

Note: You can't have a single trigger that fires before INSERT, UPDATE,
and DELETE.  At least not when defined via SQL ;-)  So you'll have to
have 3 separate statements.

HTH,
Charles


In article <2590fb58.0404140557.71480015@posting.google.com>,
cmpofu@iupui.edu says...
> I have a lab assignment that I have been struggling with.  We are
> using oracle sql.  Can someone please help me.  See the lab below.  I
> have done ques 1 - 3 thus far and am now stuck on triggers ques 4 - 6.
>
> THIS IS THE LAB:
>
> 1. Create a table called QUOTE.
> ·    Give the table an initial and next extent size of 8192
> ·    Specify a pctincrease of 0
> ·    Define the following columns using the datatypes and length listed
> below.  All columns should be mandatory except the COMMENTS column:
> o    ID            NUMBER(4)
> o    QUOTE_DATE    DATE
> o    SALES_REP_ID    NUMBER(4)
> o    CUST_NBR        NUMBER(5)
> o    PART            VARCHAR2(20)
> o    QUANTITY        NUMBER(4)
> o    UNIT_COST        NUMBER(8,2)
> o    STATUS        CHAR(1)
> o    COMMENTS        VARCHAR2(100)
> ·    Define the ID column as the primary key for the table. You can do
> this in the CREATE TABLE statement, or issue an ALTER TABLE statement
> afterwards.
>
> 2. Alter the table above to add some foreign key constraints.  Name
> these constraints QUOTE_tablename_FK, where tablename is the table
> referred to by the foreign key.
>
> For example, a foreign key on the QUOTE table referring to the PART
> table should be called QUOTE_PART_FK.
>
> ·    A foreign key on the SALES_REP_ID column should refer to the
> EMPLOYEE table.
> ·    A foreign key on the CUST_NBR column should refer to the CUSTOMER
> table.
> ·    A foreign key on the PART column should refer to the PART table.
>
> 3. Create a composite index on the CUST_NBR, PART and QUOTE_DATE
> columns.
> ·    Give the index an initial and next extent of 8192
> ·    Use pctincrease 0
> ·    Name the index whatever you'd like
>
> 4. Create a database trigger on the QUOTE table that will fire before
> an INSERT, UPDATE or DELETE operation.  Name the trigger QUOTE_TRG.
> The trigger should enforce the following rules:
>
> ·    If INSERTING or UPDATING
> o    QUOTE_DATE cannot be greater that SYSDATE (the current system date
> and time)
> o    UNIT_COST can't be greater than the UNIT_COST for this part in the
> PART table
> o    If QUANTITY is over 100, the UNIT_COST must be at least 20% less
> than the UNIT_COST for this part as listed in the PART TABLE
> ·    If INSERTING, in addition to the rules listed above:
> o    STATUS must contain a value of  P (which stands for pending)
> ·    If UPDATING, in addition to the rules listed earlier:
> o    A STATUS of P can only be changed to a STATUS of A (which stands for
> active)
> o    A STATUS of A can be changed to P, W, L or C (for pending, won, lost
> or cancelled)
> o    A STATUS of W, L or C can only be changed back to P
> ·    If DELETING
> o    STATUS must be P or C
>
> If any of these rules are violated, raise one of the following
> exceptions which you will define in the EXCEPTION portion of your
> trigger.  Raise an application error. Use whatever error numbers you'd
> like, and provide meaningful text to describe the error:
>
> ·    Quote date can't be a future date
> ·    Quoted price is too high
> ·    New quotes must have a status of P
> ·    Pending status (P) can only be changed to Approved (A)
> ·    Invalid status code
> ·    Won, Lost or Cancelled quotes can only be changed to Pending
>
> 5. Create a BEFORE UPDATE trigger on the PART table. The trigger
> should enforce the following rule:
> ·    If UNIT_COST is being updated
> o    The new price can't be lower than any of the quoted prices in the
> QUOTE table for this part, if the quote status is P or A
> o    The new price must be at least 20% more than any quoted prices in
> the QUOTE table for this part, if the quote is for a quantity > 100
> and the quote status is P or A
>
> Define a single exception that is raised when either error occurs. The
> text of the application error should indicate that the cost is invalid
> based upon outstanding quotes on the part.
>
> 6. Write a series of statements to test your new triggers:
> ·    Try to insert a row into the quote table. For the quote date,
> provide a value of SYSDATE+1. This will try to insert a row with
> tomorrow's date for the quote date.
> ·    Try to insert a row into the quote table with a price greater than
> that listed for the part in the PART table
> ·    Try to insert a row into the quote table with a quantity > 100 and a
> price > 20% off the price in the PART table
> ·    Try to INSERT a row with a STATUS other than P
> ·    Now insert a valid row so that you can test some UPDATE statements
> ·    Issue an UPDATE to modify the price to a price higher than that in
> the PART table
> ·    Issue an UPDATE to modify the quote date to SYSDATE+1
> ·    Issue an UPDATE to modify the quantity to > 100 and the price to
> something higher than 20% off the price listed in the PART table
> ·    Issue an update to modify the status from P to W
> ·    Now issue a valid update to change the status to A
> ·    Issue a delete to make sure you can't delete a row with status of A
> ·    Finally, issue an update on the PART table to set the price higher
> than the quoted price in the QUOTE table
>
> THIS IS WHAT I HAVE DONE THUS FAR:
>
> set serveroutput on;
>
> 1.
>
> CREATE table QUOTE
> (ID NUMBER(4),
> QUOTE_DATE DATE,
> SALES_REP_ID NUMBER(4),
> CUST_NBR NUMBER(5),
> PART VARCHAR2(20),
> QUANTITY NUMBER(4),
> UNIT_COST NUMBER(8,2),
> STATUS CHAR(1),
> COMMENTS VARCHAR2(100))
> Storage (INITIAL 8K
>          NEXT 8k
>          PCTINCREASE 0);
>
> ALTER TABLE QUOTE
> ADD CONSTRAINT ID_PK
> PRIMARY KEY (ID);
>
> 2.
>
> ALTER TABLE QUOTE
> ADD CONSTRAINT SALES_REP_ID_FK
> FOREIGN KEY (SALES_REP_ID)
> REFERENCES EMPLOYEE;
>
> ALTER TABLE QUOTE
> ADD CONSTRAINT CUST_NBR_FK
> FOREIGN KEY (CUST_NBR)
> REFERENCES CUSTOMER;
>
> ALTER TABLE QUOTE
> ADD CONSTRAINT PART_FK
> FOREIGN KEY (PART)
> REFERENCES PART;
>
> 3.
>
> CREATE INDEX QUOTEINDEX
> ON QUOTE (CUST_NBR, PART, QUOTE_DATE)
> STORAGE (INITIAL 8192K
>          NEXT 8192K
>          PCTINCREASE 0);
>


pgsql-sql by date:

Previous
From: Laura Scott
Date:
Subject: relation X does not exist
Next
From: CoL
Date:
Subject: Re: problem porting MySQL SQL to Postgres