Question

I want update book ant set amount-1, when after insert record to sell table.

create table book (
id number(3) not null, 
name varchar(20),
author varchar(12),
amount number(3) not null,
constraint book_pk primary key(id)
);

create table sell (
id number(3) not null, 
date varchar(20),
book_id number(3),
constraint sell_pk primary key(id)
);

I want after insert to table sell record update book table amount-1;

CREATE OR REPLACE TRIGER changes_amount_trigger
AFTER INSERT ON sell 
FOR EACH ROW
BEGIN

UPDATE BOOK SET amount = amount-1 WHERE id = book_id

END;

I not know how to get inserted record book id, to update this record in book table.

Was it helpful?

Solution 2

Data Model Assumptions:

I am assuming you will register transactions by changing the data in the SELL table through INSERT DML SQL operations. This is also supported by your set up of a DML trigger on SELL to pass its changes as SALES information to the BOOK table. This is workable.

By accident, I tried setting up the trigger a little differently and I'd like to suggest a different approach:

Consider possibly working in the opposite direction: Change book quantities directly on the BOOK table, so a single purchase of book_id = 5 would handle queries that could:

    UPDATE book SET amount = amount -1
     WHERE id = 5;  COMMIT; 

Restocking would mean increasing the quantity of available books by incrementing the AMOUNT value instead.

There are a few additional changes that might tighten up this two-table design and protect the integrity of the data within them for the longer term:

CREATE TABLE book (
    id number(3) not null, 
    name varchar(20),
    author varchar(12),
    amount number(3) not null,
    CONSTRAINT book_pk PRIMARY KEY(id)
    );


ALTER TABLE book
   ADD CONSTRAINT book_amt_ck CHECK (amount > 0);

ALTER TABLE book
   ENABLE CONSTRAINT book_amt_ck;

To prevent negative book amount (quantity) values, a TABLE CHECK CONSTRAINT would prevent the entry of values by means of arithmetic errors in DML operations such as:

    UPDATE book SET amount := amount - 1

In the example above, there is no control over decrementing the book inventory even if the quantity on hand has reached 0. Check out a few references on TABLE CHECK CONSTRAINTS to get a better understanding of what it can do for specific design situations.

Here are some design suggestions for the trigger:

  1. Changes in book quantities should be the only triggering data element that affects the SELL table.

  2. The trigger should account for changes in book quantities > 1.

        CREATE OR REPLACE TRIGGER orders_after_update
            AFTER UPDATE
               ON book
              FOR EACH ROW
    
            DECLARE
              v_amount   number;
    
            BEGIN
    
            IF (:new.amount < :old.amount ) THEN
    
               FOR v_amount in  1 .. (:old.amount - :new.amount)
               LOOP
                  INSERT INTO sell (id, date, book_id)
                  VALUES (sell_seq.nextval, sysdate, :new.id);
    
                  COMMIT;
    
               END LOOP;
    
            END IF;
    
        END; 
    

For more information on triggers and their design, check a few instances to get a better understanding of how they are designed and set up.

    CREATE SEQUENCE sell_seq
       MINVALUE 1
       START WITH 1
       INCREMENT BY 1
       CACHE 20;

We needed a sequence to populate the primary key/index of the SELL table. Oracle Sequences are useful for this purpose.

By watching the table changes with a trigger on the BOOK table, you can use the built in references which already exist when a table trigger fires. For example, BOOK.ID does not require an additional query because a trigger automatically is made aware of the beginning and ending value of each trigger monitored record.

Some useful discussions on triggers are discussed in more detail through an Internet search.

Setting Up a Foreign Key Relationship

Although the trigger will probably keep this relation clean, a Foreign Key relation between elements BOOK.ID and SELL.BOOK_ID would be good, otherwise queries on Sales transactions may yield book sales without any descriptive production information. The following is a reference on Foreign Keys and their use.

CREATE TABLE sell (
    id number(3) not null, 
    date varchar(20),
    book_id number(3)
    );


ALTER TABLE table_name
   ADD CONSTRAINT sell_fk
   FOREIGN KEY (book_id)
   REFERENCES book(id);

OTHER TIPS

Try like this,

CREATE OR REPLACE TRIGGER changes_amount_trigger
AFTER INSERT ON sell 
FOR EACH ROW
BEGIN
     UPDATE BOOK SET amount = amount-1 WHERE id = :new.book_id;
END;
/

Do you already have records in sell table and want to update the amount in book table ? if this is your case you can update your book.amount as following:

update book  b
set b.amount = b.amount - (select count(*) from sell s where b.id = s.book_id);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top