How can i Update inventory using TRIGGER - mysql

Well here is the problem...I want to update the inventory table at my database which includes
Sale(ProductID,Quantity,Price)
Invlevel(ProductID,Quantity)
I want to use triggers for this update. I have to use 2 triggers (I think). 1 at the sale tables which will be something like
CREATE TRIGGER `sale_AINS` AFTER INSERT ON sale FOR EACH ROW
begin
update Invlevel set quantity = Invlevel.quantity-"sale.quantity" where
Invlevel.ProductID = "sale.ProductID";
END
with this trigger, when a sale comes up, I want to adjust the inventory level at the product which the sale came to. However, even though this trigger has no errors and runs properly when I insert into sale table, it doesn't make any changes at the Invlevel table and I don't know why ( :# ).
Moreover, I made the trigger at the Invlevel table like that
CREATE TRIGGER `invlevel_AUPD` after UPDATE on invlevel FOR EACH ROW
if invlevel.quantity < 20
begin
insert into orders
(select productid,amount from reorder where reorder.productid = invlevel.productid )
end
*(orders,reorder are other tables)
It says to me I have syntax error which I don't know what it is and also even if I find it I can't even check the logic because the other trigger isn't even working... Any thought or help about it would be really helpful.

Try
First trigger
CREATE TRIGGER sale_AINS
AFTER INSERT ON sale
FOR EACH ROW
UPDATE invlevel
SET quantity = quantity - NEW.quantity
WHERE productid = NEW.productid;
In this trigger you don't need BEGIN END block since there is only one statement. In order to access column values or a row(s) that being inserted you need to use NEW keyword.
And the second one
DELIMITER $$
CREATE TRIGGER invlevel_AUPD
AFTER UPDATE ON invlevel
FOR EACH ROW
BEGIN
IF NEW.quantity < 20 THEN
INSERT INTO orders (productid, amount)
SELECT productid, amount
FROM reorder
WHERE productid = NEW.productid;
END IF;
END$$
DELIMITER ;
In the second trigger IF statement was out of BEGIN END block and syntax for IF was wrong. It should be IF ... THEN ... END IF;. And the same problems with a NEW keyword.
Here is SQLFiddle demo
You can put your IF condition into WHERE clause and make it more succinct like this
CREATE TRIGGER invlevel_AUPD
AFTER UPDATE ON invlevel
FOR EACH ROW
INSERT INTO orders (productid, amount)
SELECT productid, amount
FROM reorder
WHERE productid = NEW.productid
AND NEW.quantity < 20;
Here is updated SQLFiddle demo

Related

Why getting a Syntax error in MySQL Trigger query?

I have learned the triggers in Oracle SQL, and not that well versed in MySQL. I was trying to convert a trigger command from Oracle to MySQL. First of all, I am not able to find the when statement, I found the if else instead. This is what I wrote:
create trigger overdraft
after update on account
for each row
begin
if account.balance < 0 then
insert into borrower(select customer_name, account_number from depositor where new.account_number=depositor.account_number);
insert into loan(select new.account_number, new.branch_name, new.balance);
update account set balance = 0 where account.account_number = new.account_number;
end if;
end;
But I am getting three syntax errors, first at end of first insert statement at the left parenthesis saying, "Statement is incomplete, expecting : ','". Other two are on each of the ends saying "end is not valid at this position: Expecting BEGIN, EOF,....". What is wrong with me code? I am having hard time figuring out.
There are several things. delimiter probably being one of them:
delimiter $$
create trigger overdraft before update on account
for each row
begin
if new.balance < 0 then
insert into borrower (customer_name, account_number) -- column list here
select d.customer_name, d.account_number
from depositor d
where new.account_number = d.account_number;
insert into loan (account_number, branch_name, balance) -- column list here
select new.account_number, new.branch_name, new.balance;
set new.balance = 0;
end if;
end;$$
delimiter ;
Notes:
delimiter is needed so the definition of the trigger does not end at the first semi-colon.
The reference in the initial if (account.balance) is not understood, because account is not defined.
You want to update the balance in the row with the trigger. Hence, you want a before update trigger, not an after update trigger.
When inserting rows into a table, you should always list the columns being inserted. I have speculated on the column names above.
Simply use Delimiter like this.
I thought that you had tested all the insert.
Inser ino mus be like the example wthat i written,but the columnnames could differ.
As i described you can't use the same table in your trigger that fired the trigger. so use the set paramter to change the balance to 0
DELIMItER //
create trigger overdraft
after update on account
for each row
begin
if account.balance < 0 then
insert into borrower (customer_name, account_number) select customer_name, account_number from depositor
where new.account_number=depositor.account_number;
insert into loan (account_number, branch_name, balance) select new.account_number, new.branch_name, new.balance;
set new.balance = 0;
end if;
end;
DELIMItER ;

How to fix my trigger which isn't deleting

I am working on a e-commerce site for a school project and i need to add a trigger in my project.
I choose to add a trigger which, when the product stock is equal to zero, the product is deleted and added in a historic table.
CREATE TRIGGER stock_produit_0 BEFORE UPDATE
ON produit FOR EACH ROW
BEGIN
IF OLD.StockProduit = 0 THEN
INSERT INTO historique_produit(
idProduit,
PrixProduit,
PoidProduit,
NomProduit,
DescriptionProduit,
CouleurProduit,
idclient,
dateDelete)
VALUES(
OLD.idProduit,
OLD.PrixProduit,
OLD.PoidProduit,
OLD.NomProduit,
OLD.DescriptionProduit,
OLD.CouleurProduit,
OLD.idclient,
NOW());
DELETE FROM produit WHERE idProduit = OLD.idProduit;
END IF;
END
Now, the trigger is working on the server but, when i buy a product, the product stock go to 0 but is not deleted
I decided to cut my trigger in two other trigger.
The first one is the trigger which insert into the table historique_produit when the stock equal to zero and it's working.
But now, i have do code something which DELETE my product from produit when the stock equal to zero.
I do not know if this is possible.
If it's not, i think i will keep my product in the table and i won't show it on the page which show the product
BEGIN
IF NEW.StockProduit = 0 THEN
BEGIN
INSERT INTO historique_produit(
idProduit,
PrixProduit,
PoidProduit,
NomProduit,
DescriptionProduit,
CouleurProduit,
idclient,
dateDelete)
VALUES(
OLD.idProduit,
OLD.PrixProduit,
OLD.PoidProduit,
OLD.NomProduit,
OLD.DescriptionProduit,
OLD.CouleurProduit,
OLD.idclient,
NOW());
END;
END IF;
END

mysql double trigger two updates together

After trying to create a new trigger in invoices table to UPDATE `invoices` SET invoices.`owes` = (`owes` - `paid`);
I get an error because I already that another trigger in payments that is updating. (see below)
I'm looking to keep the existing trigger below, but how to modify it to also update owes to (owes - paid) in the invoices table.
CREATE TRIGGER `after_payment_update` AFTER UPDATE
ON `payments`
FOR EACH ROW UPDATE `invoices`
SET invoices.`paid` = (SELECT SUM(payments .`payment`)
FROM payments WHERE payments.`invoice` = invoices.`invoice`)
You can't create a second trigger that "triggers" on the same action as another trigger. Instead you would use a DELIMITER $$ statement like below and fill your trigger with all the relevant code you want executed.
DELIMITER $$
CREATE TRIGGER after_update_payments
AFTER UPDATE ON payments
FOR EACH ROW BEGIN
UPDATE invoices
SET NEW.paid = (SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice),
NEW.owes = (owes -(SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice));
END $$
DELIMITER ;
You don't actually need a DELIMITER in the trigger above, so I will show you an example where you would need to use it:
DELIMITER $$
CREATE TRIGGER after_update_payments
AFTER UPDATE ON payments
FOR EACH ROW BEGIN
IF (some condition here) THEN
UPDATE invoices
SET NEW.paid = (SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice),
NEW.owes = (owes -(SELECT SUM(payment) FROM payments WHERE invoice = NEW.invoice));
END IF;
END $$
DELIMITER ;
As a general rule, if you need to execute multiple statements that need a ; at the end of them, you need to use a DELIMITER. If this still doesn't make sense, a great explanation for delimiters can be found here.
Now, on a side-note, I don't think this approach is the most optimal one. What I would do in your situation is create a view that combines these tables. For example:
CREATE
ALGORITHM = UNDEFINED
DEFINER = `root`#`localhost`
SQL SECURITY DEFINER
VIEW invoice_payments_view AS (
SELECT
t1.*,
SUM(t2.payment) as amount_paid,
SUM(t2.owes - SUM(t2.payment)) as amount_owed
FROM invoices t1
JOIN payments t2 ON (t1.invoice=t2.invoice)
GROUP BY t1.invoice
)
Then to access the amount_paid and amount_owed columns, you would simply query the following:
SELECT invoice, amount_paid, amount_owed FROM invoice_payments_view
WHERE invoice=1;
Note that I am by no means an expert on this topic, and I am only showing you how I would approach this situation. Also, I didn't test any of this code, so you might need to modify it slightly. If you have any issues let me know and I can update.

PHPmyAdmin mySQL Trigger: Upddate the parent table when child table was inserted, updated or deleted

I need some help with getting the syntax right to define a trigger in PHPmyAdmin.
What I have:
2 tables - invoice and invoiceitem
tbl_invoice has a field 'Total' which should show the sum of the 'Extended' price of the table invoiceitem
tbl_invoiceitem has 2 triggers that update the 'Extended' before_insert and before_update
What I try to accomplish:
Calculate the sum of all items for an invoice and update the 'Total' price in tbl_invoice after either new items are inserted or if the price or quantity for an existing item was updated.
I try to do this in PHPmyAdmin.
The error message is
I hope somebody can give mt a hint into the right direction. Just started with triggers and don't seem to find solution with a couple of days searching the internet.
Thank you for help in advance.
Cheers, Oliver
I can see 2 syntax errors in your code:
The delimiter commands should be outside of the trigger definition, not inside of it. Phpmyadmin should take care of this.
The commands within the begin ... end block should be terminated by semicolon (;), not by whatever you provide in the delimiter command.
I did not check if your sql commands within the trigger make sense, but the where condition of the set command does not seem right.
Ok, found a work around:write the full create trigger statement in a file and import with PHPmyAdmin. As 'Shadow' pointed out there was also a problem in the where conditions.
Below the corrected triggers that worked in my scenario.
There is a lot of examples on the net to get triggers done with the mysql client. This way you can use the exact syntax that you would type into a client and than import into PHPmyAdmin in case you can't reach the server your using with a command shell client.
Hope this helps other newbies.
Cheers, Oliver
-- after_insert trigger for InvoiceItem to Calculate the Total in Invoice
------------------------------------------------------------------------
DELIMITER //
CREATE TRIGGER `InvoiceItem_After_Insert` AFTER INSERT ON `invoiceItem`
FOR EACH ROW
BEGIN
SET #InvoiceNumber = NEW.InvoiceFK;
SET #ItemTotal = (SELECT SUM(Extended) FROM InvoiceItem WHERE InvoiceFk = #InvoiceNumber);
UPDATE Invoice SET Total = #ItemTotal WHERE id = #InvoiceNumber;
END
//
DELIMITER ;
-- after_update trigger for InvoiceItem to Calculate the Total in Invoice
------------------------------------------------------------------------
DELIMITER //
CREATE TRIGGER `InvoiceItem_After_Update` AFTER UPDATE ON `invoiceitem`
FOR EACH ROW
BEGIN
SET #InvoiceNumber = NEW.InvoiceFK;
SET #ItemTotal = (SELECT SUM(Extended) FROM InvoiceItem WHERE InvoiceFk = #InvoiceNumber);
UPDATE Invoice SET Total = #ItemTotal WHERE id = #InvoiceNumber;
END
//
DELIMITER ;
-- after_delete trigger for InvoiceItem to Calculate the Total in Invoice
----------------------------------------------------------------------
DELIMITER //
CREATE TRIGGER `InvoiceItem_After_Delete` AFTER DELETE ON `invoiceItem`
FOR EACH ROW
BEGIN
SET #InvoiceNumber = OLD.InvoiceFK;
SET #ItemTotal = (SELECT SUM(Extended) FROM InvoiceItem WHERE InvoiceFk = #InvoiceNumber);
UPDATE Invoice SET Total = #ItemTotal WHERE id = #InvoiceNumber;
END
//
DELIMITER ;
-----------------------------------------------------------------
The next 2 triggers are just single statement and are calculate the 'Extended' column in the InvoceItem table
---------------------------------------------------------------------
-- Calculate new 'Extended' price before insert
CREATE TRIGGER `InvoiceItem_Before_Insert` BEFORE INSERT ON `invoiceitem`
SET NEW.Extended = ROUND(NEW.Quantity * NEW.Price,2)
-------------------------------------------------------------------
-- Calculate new 'Extended' price before update
CREATE TRIGGER `InvoiceItem_Before_Update` BEFORE UPDATE ON `InvoiceItem`
FOR EACH ROW
SET NEW.Extended = ROUND(NEW.Quantity * NEW.Price,2);

How can I make trigger from two different tables?

How can I make trigger to read from two separated attribute in two different tables and then
calculate something .
this is the code I want to make but the mysql says it has problem
CREATE TRIGGER `fee_calculate` BEFORE INSERT ON `BookingRoom`
FOR EACH ROW BEGIN
SET NEW.fee = `Booking.Night_Qty` * `Room.RoomPrice` ;
END
I Think It Should Help You
I made some assumptions:
I assumed you wanted to update the reorders table with a productID that matches the Products table. (you can do an insert but may run into PK issues depending on how you have your table set up).
I assumed that the reorder amount will be placed there.
I did NOT include transaction statements, I would recommend adding these so it's logged.
CREATE trigger updateprod
on Products
for update as
begin
declare #qtyonhand int,
#reorder int
if update(QtyonHand)
begin
select #qtyonhand = QtyonHand,#reorder = ReorderAmount from inserted
if #qtyonhand < #reorder
begin
update Reorders set ReorderAmount = #reorder, ReorderDate = getdate()
end
else if #qtyonhand >= #reorder
begin
delete from reorders where ProductID = ProductID
end
end
end