What I want to do is to add some credit (10% of user´s credit) to user´s account with each 3rd, 6th, 9th and 12th (not more) user added into database under this user´s invite link (but invite link isn´t essential here - each user has index column with ID of his invitator).
So something like this (sorry for "pseudocode", I never had to use the trigger and probably won´t have to any soon, so I have no idea how to write it properly):
UPDATE accounts.credit = accounts.credit + (accounts.credit/10)
ON INSERT INTO users (AND when inserted row % 3 == 0 to some user)
WHERE k_user = this
Or is there any easier way how to do this? I could handle PHP, but I think the script can execute only if user visits the site...
Consider using triggers https://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html
delimiter $$
CREATE TRIGGER upd_check AFTER INSERT ON users
FOR EACH ROW
BEGIN
IF NEW.id % 3 = 0 THEN
UPDATE accounts SET credit = credit + (credit / 10) where k_user = NEW.id
END IF;
END;$$
delimiter ;
Related
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 ;
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
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);
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
I have a table warehouse where I have information about articles in my store (article id as foreign key and quantity). Then, I have another table, shoppinglist where I have a clients id, article id and quantity. Lets say, that client wants to buy 3 articles but theres only one article available. How to write a trigger which help me to prevent from buying too much?
I tried this:
DELIMITER $$ CREATE TRIGGER check BEFORE INSERT ON shoppinglist FOR EACH ROW BEGIN IF warehouse.quantity < shoppinglist.quantity THEN CALL fail('You cant buy that much'); END IF; END $$ DELIMITER;
but this seems not to work. I mean, when I do:
INSERT INTO shoppinlist (clients_id, article_id, quantity) VALUES (1, 2, 100);
having only 2 articles with id = 2 on warehouse its ok, its possible. What did I do wrong?
What specific article would warehouse.quantity or shoppingList.quantity refer to in your code?
Also, check is a reserved keyword.
Try this:
DELIMITER $$
CREATE TRIGGER qtyCheck BEFORE INSERT ON shoppinglist
FOR EACH ROW
BEGIN
SET #qty = (SELECT quantity FROM warehouse WHERE article_id = NEW.article_id);
IF #qty < NEW.quantity THEN
CALL fail('You cant buy that much');
END IF;
END $$
DELIMITER ;
Note that I renamed the trigger, I'm guessing the name of the article_id column on the warehouse table, I used the NEW variable instead of shoppingList within the body of the trigger, and you need a space before the semicolon in DELIMITER ;, though this might've been a typo when posting.
Finally, you may get the following error if the fail function isn't defined. It doesn't exist on my system...
ERROR 1305: PROCEDURE testing.fail does not exist