MySQL Trigger - Where am I going wrong - mysql

Can someone tell me where I'm going wrong in creating this trigger in MySQL? Every time I try to create it, it keeps telling me there is an error.
USE `cl11-onestock`;
DELIMITER //
CREATE TRIGGER audit_insert
AFTER INSERT
ON stock_usage FOR EACH ROW
BEGIN
SET uUid = (SELECT UUID());
SET stockUsageId = (SELECT NEW.stock_usage_id);
SET siteId = (SELECT NEW.site_id);
SET date = (SELECT NEW.date);
SET patientName = (SELECT NEW.patient_name);
SET dentistDiscountId = (SELECT NEW.dentist_discount_id);
SET itemId = (SELECT NEW.item_id);
SET quantity = (SELECT NEW.quantity);
SET priceIncDiscount = (SELECT NEW.price_inc_discount);
SET vat = (SELECT NEW.vat);
SET priceIncVat = (SELECT NEW.price_inc_vat);
SET createdAt = (SELECT NEW.created_at);
SET updatedAt = (SELECT NEW.updated_at);
INSERT INTO stock_audit VALUES
(uUid, stockUsageId, siteId, date, patientName, dentistDiscountId, itemId, quantity, priceIncDiscount, vat, priceIncVat, createdAt, updatedAt);
END; //
DELIMITER ;

You need to use the keyword new to access the field values after insert and not like you are doing with select and you can use directly inside the insert query
So the trigger should be as
DELIMITER //
CREATE TRIGGER audit_insert
AFTER INSERT
ON stock_usage FOR EACH ROW
BEGIN
INSERT INTO stock_audit VALUES
(new.UUID, NEW.stock_usage_id, NEW.site_id, NEW.date, NEW.patient_name, NEW.dentist_discount_id, NEW.item_id, NEW.quantity, NEW.price_inc_discount, NEW.vat, NEW.price_inc_vat, NEW.created_at, NEW.updated_at);
END; //
DELIMITER ;

Related

Can we execute IF ELSE without the procedure in mysql

Please find my code and provide me any alternate way to execute this code without procedure.
delimiter $$
create procedure dm()
begin
IF EXISTS (select * from sainikpuri_purchases where barcode = 12012271314) THEN
update sainikpuri_purchases set quantity = quantity+2 where barcode = 12012271314;update purchases set quantity = quantity-2 where barcode = 12012271314;
ELSE
INSERT INTO sainikpuri_purchases(id, vendor_name, quantity, from_location, location, cost, cost_of_price,invoice_number,serial_number,sarees_category,paid_gst,profit_percentage,sales_price,tag,barcode,discount,created_at,updated_at,status) SELECT id, vendor_name, 2, 'KPM', 'SNP', cost, cost_of_price,invoice_number,serial_number,sarees_category,paid_gst,profit_percentage,sales_price,tag,barcode,discount,created_at,updated_at,status FROM purchases where barcode = '12012271314';update sainikpuri_purchases set updated_at = current_timestamp where barcode = '12012271314';update purchases set quantity = quantity-2 where barcode = '12012271314';
END IF;
end $$
delimiter ; call dm();```

SQL can I create an if statement if subquery returns more than 1 row?

Hi I'm making a procedure "AddToCart" I want to check if there is row with the same column values and if there is update it, if not insert a new row. I keep getting subquery returns more than 1 row.
CREATE PROCEDURE AddToCart(thisCustomerID INT, thisOrdersID INT, thisShoeID INT, thisQuantity INT)
BEGIN
DECLARE any_rows_found int;
IF (thisOrdersID IS NULL)
THEN
INSERT INTO orders (Date, CustomerID)
VALUES (CURRENT_DATE, thisCustomerID);
SELECT COUNT(*)
INTO any_rows_found
FROM Shoe_Orders
WHERE OrdersID = thisOrdersID
AND ShoeID = thisShoeID;
IF (any_rows_found > 0)
THEN
UPDATE shoe_orders
SET Quantity = Quantity + thisQuantity
WHERE ShoeID = thisShoeID
AND OrdersID = thisOrdersID;
ELSE
INSERT INTO shoe_orders (ShoeID, OrdersID, Quantity)
VALUES (thisShoeID, (SELECT ID
FROM orders
WHERE CustomerID = thisCustomerID
AND Date = CURRENT_DATE), thisQuantity);
END IF;
END IF;
END //

LAST INSERT ID SQL Subquery returns more than one row

I have the below Stored Procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS spCashDonation$$
CREATE PROCEDURE spCashDonation(IN fname varchar(50),IN lname varchar(50),IN telNo bigint, IN pmode tinyint,IN amt decimal(8,2), OUT rno varchar(20))
BEGIN
Set #rmain := (select trim(concat('DNB', DATE_FORMAT(CURRENT_DATE(), '%y'), DATE_FORMAT(CURRENT_DATE(), '%m'))));
IF ((trim(DATE_FORMAT(CURRENT_DATE(),'%m')) = 01) OR (trim(DATE_FORMAT(CURRENT_DATE(),'%m')) = 1)) THEN
Set #rpart = 1;
END IF;
IF ((trim(DATE_FORMAT(CURRENT_DATE(),'%m')) != 01) OR (trim(DATE_FORMAT(CURRENT_DATE(),'%m')) != 1)) THEN
Set #rpart := (select coalesce(max(ReceiptPart),0) from Donation) + 1;
END IF;
INSERT INTO Donation (ReceiptMain, ReceiptPart, firstName, lastName, telNo, payMode, Amount) VALUES (#rmain, #rpart, fname, lname, telNo, pmode, amt);
Set #lid := (select LAST_INSERT_ID()from donation);
select concat(ReceiptMain,ReceiptPart) into rno from donation where id = #lid;
END$$
DELIMITER ;
Call spCashDonation ('RAJIV','IYER',7506033048,0,1000,#rno);
select #rno;
When the table has no record, the first insert goes through fine. The upon the second insert it throws an error as
Error Code: 1242. Subquery returns more than 1 row
When I query for the last insert id, I get more than 1 value. So, I modified the last part of the procedure to:
Set #lid := (select max(LAST_INSERT_ID()) from donation);
Please advice, if this is fine as it should not hinder any concurrent inserts and future CRUD operations. Thanks in advance.
Set #lid := (select LAST_INSERT_ID() from donation);
In the above line remove the FROM statement. If more than one record in the Donation table it will return the same number of times the LAST_INSERT_ID() value.
So simply use Set #lid := (SELECT LAST_INSERT_ID()); it will work in your case.

MySQL if not exists by two columns update other

I want to insert record if it not exists by 2 columns, and if exists update column 3, here's the query:
INSERT INTO aktai_islaidos_id (akto_id, islaidos_id, savikaina)
SELECT * FROM (SELECT ? as a, ? as b, ? as c) AS tmp
WHERE NOT EXISTS (
SELECT akto_id, islaidos_id, savikaina FROM aktai_islaidos_id
WHERE akto_id = a AND islaidos_id = b
) ON DUPLICATE KEY UPDATE savikaina = VALUES(c);
Now I'm getting error what c not exists in fields list, I understand why, but I didn't know how to complete this query correctly and didn't find any examples like what only where selects duplicate all columns, thanks!
EDIT:
Figured out this with stored procedure:
CREATE PROCEDURE update(
IN akt_id INT,
IN isl_id INT,
IN sav INT)
BEGIN
IF (SELECT count(*) FROM aktai_islaidos_id WHERE akto_id = akt_id AND islaidos_id = isl_id) > 0 THEN
BEGIN
UPDATE aktai_islaidos_id SET savikaina = sav WHERE akto_id = akt_id AND islaidos_id = isl_id;
END;
ELSE
BEGIN
INSERT INTO aktai_islaidos_id (akto_id, islaidos_id, savikaina) VALUES (akt_id, isl_id, sav);
END;
END IF;
END

MySQL, CONCAT in SELECT statement

(SELECT CONCAT(#I, '_Delta') FROM table WHERE id_tb = #ID)
I'm using the above statement as part of an INSERT. The problem is the whole line is being translated to the value of #I (this is an index, values are i.e. 0, 1, 2, ...). So, instead of getting the output of the SELECT I'm getting 0, 1, 2, ...
The expected value of the CONCAT is like "0_Delta", then "1_Delta", etc. Replacing the CONCAT by one of this works.
Any comments will be appreciated. Thanks!
[code]
DROP TABLE IF EXISTS xxx_tb;
CREATE TABLE xxx_tb
(
i_Validity INT,
Delta INT
);
DROP TRIGGER IF EXISTS AFTER_INSERT_ON_tb_in;
DELIMITER $$
CREATE TRIGGER AFTER_INSERT_ON_tb_in
AFTER INSERT ON tb_in
FOR EACH ROW
BEGIN
SET #ID = NEW.id_tb;
SET #TYPE = (SELECT Type FROM header WHERE id_tb = #ID);
IF #TYPE = 'abcd' THEN
SET #SAMPLES = (SELECT SampleNumber FROM table WHERE id_tb = #ID);
IF(#SAMPLES > 1) THEN
SET #I = 0;
WHILE(#I < #SAMPLES) DO
INSERT INTO xxx_tb
(
i_Validity,
Delta
)
VALUES
(
(SELECT 0_Validity FROM table WHERE id_tb = #ID),
(SELECT CONCAT(#I, '_Delta') FROM table WHERE id_tb = #ID)
);
SET #I = #I + 1;
END WHILE;
END IF;
END IF;
END$$
DELIMITER ;
[code]
delta is declared as an integer. You are getting a silent conversion from the string value. Because #i is at the beginning, that is the value you are getting.
You can try declaring it as varchar(255) if you want a string value.
Your insert can be written more easily as an insert . . . select:
INSERT INTO xxx_tb(i_Validity, Delta)
SELECT `0_Validity`, CONCAT(#I, '_Delta')
FROM table WHERE id_tb = #ID);