Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

A trigger to give a 10 per cent discount to a regular customer

3128080Dec 17 2015 — edited Dec 17 2015

Hi,

I am trying to create a trigger to give a discount of 10% of the field 'totalCost' in the bookings table, if the 'statusname' is regular in the Passengers table. Below is what I have come up with so far. But I know its wrong. Can you please help?

create or replace TRIGGER Ten_Percent_Discount

BEFORE UPDATE ON Bookings

FOR EACH ROW

BEGIN

UPDATE Bookings b

SET b.TotalCost = 0.10 * TotalCost

WHERE Passengers.StatusName = 'Regular';

END;

Thanks,

Fareedh

This post has been answered by PamNL on Dec 17 2015
Jump to Answer

Comments

PamNL

You are trying to update the table that is updating .. simple do this

  1. create or replace TRIGGER Ten_Percent_Discount  
  2. BEFORE UPDATE ON Bookings 
  3. FOR EACH ROW 
  4. BEGIN 
  5.   :New.total_cost = 0.90 * :New.Total_Cost;
  6. END; 

Assuming you want to give 10% discount instead of 90% ;-).

And where does your Passengers.Statusname come from :-)?

3128080

Hi,

Thanks for the response

Its from the Passengers table.

Thanks,

Fareedh

PamNL
Answer

Assuming you have a passenger_id in your bookings table you probably can use something like this

eate or replace TRIGGER Ten_Percent_Discount  
BEFORE UPDATE ON Bookings 
FOR EACH ROW 

CURSOR C_Passengers
IS
SELECT Status_Name
FROM   Passengers
WHERE  Passenger_Id = :NEW.Passenger_Id
;

l_status_name Passengers.Status_Name%TYPE;

BEGIN 

  OPEN  C_Passengers;
  FETCH C_Passengers INTO l_status_name;
  CLOSE C_Passengers;
 
  IF l_status_name = 'Regular'
  THEN
    :New.total_cost = 0.90 * :New.Total_Cost;
  END IF;

END; 

Marked as Answer by 3128080 · Sep 27 2020
PamNL

Little type, use StatusName rather than Status_Name of course ..

3128080

Hi,

Thanks for your help. But can you please explain on what the trigger is doing as I am really new to triggers and does it execute the trigger when I update the statusname?

Thanks,

Fareedh

PamNL

And TotalCost rather than Total_Cost :-)

3128080

I am getting a syntax error on this line called something expected

:New.TotalCost = 0.90 * :New.TotalCost;

BluShadow

3128080 wrote:

Hi,

I am trying to create a trigger to give a discount of 10% of the field 'totalCost' in the bookings table, if the 'statusname' is regular in the Passengers table. Below is what I have come up with so far. But I know its wrong. Can you please help?

  1. create or replace TRIGGER Ten_Percent_Discount  
  2. BEFORE UPDATE ON Bookings 
  3. FOR EACH ROW 
  4. BEGIN 
  5. UPDATE Bookings b 
  6. SET b.TotalCost = 0.10 * TotalCost 
  7. WHERE Passengers.StatusName = 'Regular'
  8. END

Thanks,

Fareedh

This is business logic and really shouldn't be something you put in a trigger.  It should be at the application/business layer of your coding, not the database layer.

Triggers should be used to adjust or default values on the table to which the trigger is associated, and should ideally be the minimal code to allow for the trigger to execute quickly (consider what happens if you have to populate the table with a large quantity of data - the trigger has to fire for each row inserted).

Move this logic to your business layer where you can query the other table to determine the status and adjust the cost accordingly as the booking is inserted/updated.

3128080

Hi,

Thanks for the reply. I totally understand that however this is for my assignment and it requires a business rule trigger and I could not think of anything else.

Can you also please tell me on why I am getting a syntax error on this line  :New.TotalCost = 0.90 * :New.TotalCost;

Thanks

PamNL

I agree that this logic should not be in a trigger (nothing should be in a trigger as far as I'm concerned ;-)).

However, just to get this working ... what is your syntax error? Maybe submit your code as you have it now?

I think you missed :New.TotalCost := 0.90 * :New.TotalCost;

So the : should be before the =.

You seem fairly new to PL/SQL, this is not a production system thing is it?? Looks more like an excercise to learn PL/SQL?

3128080

Hi,

This is just for an assignment. I am really really new PL/SQL haha. I agree with you guys, but I had to write a trigger and the database itself is fairly simple.

Thank you so much for you help. Can you just tlel on when the tirgger will execute and explain what it is doing?

Thanks,

Fareedh

vijayrsehgal-Oracle

As Blu has already suggested you should not be using Trigger, but the line of code giving you error is due to "=" instead of ":="

the code should have line as below

:New.TotalCost := 0.90 * :New.TotalCost;

3128080

Hi

I am also getting this error

Error(7,26): PLS-00049: bad bind variable 'NEW.PassengerNumber'

Sorry to be so annoying

Thanks

PamNL

It will fire when you update anything in the bookings table.

I think your trigger should actually be on insert, because if you create a new booking it wll get the full cost and ONLY when you update the booking the passenger gets the 10% discount.

So you can test by entering a passenger in the table, then insert something in the booking table (nothing happens). Now update the booking (ANY field) and your total cost will be reduced.

Now for the fun part, update again ;-).

And again

And again ...

PamNL

And to be sure you get the point .. check TotalCost after each update ;-)

BluShadow

PamNL wrote:

It will fire when you update anything in the bookings table.

I think your trigger should actually be on insert, because if you create a new booking it wll get the full cost and ONLY when you update the booking the passenger gets the 10% discount.

Even better it should be on INSERT and UPDATE, so it can fire whether it's a new data or updated data, providing the UPDATE is coded to give a reduction on the original cost/price and not to keep applying discounts again and again on the current value.

3128080

Hi

I am also getting this error

Error(7,26): PLS-00049: bad bind variable 'NEW.PassengerNumber'

Sorry to be so annoying

Thanks

PamNL

That's fine .. what does your passenger and booking table look like? I had to guess on the foreign key in bookings to go the passenger table ..

3128080

SELECT PASSENGERNUMBER,

  TITLE,

  STATUSNAME,

  FIRSTNAME,

  SURNAME,

  FIRSTLINEADDRESS,

  SECONDLINEADDRESS,

  CITY,

  POSTCODE,

  CONTACTTELEPHONENUMBER,

  EMAILADDRESS,

  JOURNEY_JOURNEYNUMBER

FROM PASSENGERS ;

SELECT BOOKINGID,

  DATEOFBOOKING,

  TRAVELDATE,

  STOPS,

  TOTALADULTS,

  TOTALCHILDREN,

  CARDTYPE,

  CARDNUMBER,

  EXPIRYDATE,

  TOTALCOST,

  PASSENGERS_PASSENGERNUMBER,

  SERVICES_SERVICENUMBER

FROM BOOKINGS ;

ABove is booking and passengers

Thanks

Chris Hunt

The problem with this approach is that the trigger fires every time the booking record is updated for any reason, and each time it does the cost is reduced by 10%. Customer changes delivery date? knock off 10%. Customer changes order amount? knock off another 10% etc...

Possibly better to have a new column: discount_amount, that has a default value of 0, but you set it to 10% for regular customers.

How will you deal with cases where the passenger status is changed to regular for a passenger that has existing booking records?

PamNL

Create or replace TRIGGER Ten_Percent_Discount  
BEFORE INSERT ON Bookings 
FOR EACH ROW 

CURSOR C_Passengers
IS
SELECT StatusName
FROM   Passengers
WHERE  PassengerNumber = :NEW.Passengers_PassengerNumber
;

l_status_name Passengers.StatusName%TYPE;

BEGIN 

  OPEN  C_Passengers;
  FETCH C_Passengers INTO l_status_name;
  CLOSE C_Passengers;
 
  IF l_status_name = 'Regular'
  THEN
    :New.totalcost := 0.90 * :New.TotalCost;
  END IF;

END; 

PamNL

I hoped he would figure that out himself ;-)

3128080

I did, as soon as you said foreign key in the booking table. I am like oh yes hahah.

Thank you so much

1 - 23
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jan 14 2016
Added on Dec 17 2015
23 comments
4,455 views