I'm trying to create a after insert trigger on vitamin to insert the new data into vitamin_variety with cross join select statement that I created. But somehow when new rows are inserted, the trigger does not insert that new rows into vitamin_variety. I use select statements with join and it works good on it's own but when I use it to insert into select statement, it does nothing.
My code
BEGIN
INSERT INTO
vitamin_variety (extreme_name,regular_name, price_variety_extreme,price_variety_regular)
SELECT sel_extreme.name as `extreme_name`,sel_regular.name as `regular_name`,sel_extreme.ext,sel_regular.reg FROM
(SELECT sel.name as `name`,sel.id as `id`,sel.extreme as `ext` FROM
(SELECT new.vitamin_name as `name`,new.vitamin_id as `id`,CASE WHEN new.vitamin_name LIKE 'extreme%' THEN new.price END AS `extreme`
FROM vitamin) AS sel
WHERE sel.extreme IS NOT NULL) AS sel_extreme
CROSS JOIN
(SELECT sel.name as `name`,sel.id as `id`, sel.regular as `reg` FROM
(SELECT new.vitamin_name as `name`,new.vitamin_id as `id`,CASE WHEN new.vitamin_name NOT LIKE 'extreme%' THEN new.price END AS `regular`
FROM vitamin) AS sel
WHERE sel.regular IS NOT NULL) AS sel_regular
WHERE sel_regular.id <= sel_extreme.id
END
EDITED
Here's the FIDDLE
Related
This is my first trigger in MySql and I am having a few problems. I tried both of these pieces of code but both would not compile. I got it to work without the where clause.
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details
FOR EACH ROW
INSERT INTO sql_changes
SET
sc_table='book_room',
sc_reason='DINNER1',
sc_key='bh_no=NEW.bh_no,date=NEW.md_date',
sc_value='1',
sc_done =0
WHERE not exists (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1)
CREATE TRIGGER ins_meal_details AFTER INSERT meal_details FOR EACH ROW
BEGIN
IF NOT EXISTS (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) THEN
INSERT INTO sql_changes (sc_table, sc_reason, sc_key, sc_value, sc_done )
VALUES ('book_room','DINNER1', 'bh_no=NEW.bh_no,date=NEW.md_date','1', 0);
END IF
END
CREATE TRIGGER ins_meal_details
AFTER INSERT
ON meal_details
FOR EACH ROW
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
SELECT 'book_room',
'DINNER1',
CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),
1,
0
WHERE NOT EXISTS (SELECT 1
FROM booking
WHERE bh_no = NEW.bh_no
AND bo_date = NEW.md_date
AND bo_meals < 1);
MySql did not like the select/where exists in my code when there is no table specified. This was due to using version 5.6 of MySql server.
This will not work: select 'works' where exists (select 1 from my-table)
The fix would be thanks to #akina to add from DUAL. The best solution.
I got round it by using a count(*) instead :-
DROP TRIGGER IF EXISTS ins_meal_details;
DELIMITER //
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details FOR EACH ROW
BEGIN
IF (select count(*) from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) > 0 THEN
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
VALUES ('book_room','DINNER1', CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),'New Value', 0);
END IF;
END//
DELIMITER ;
while creating a procedure in MYSQL i am facing a problem as, condition runs 'IF' statement and runs 'ELSE' statements too. just because an insert statement inside 'IF'.
insert into Userverified (UserID, Mobile, PIN,uname,unameid)
select NextUserID(),Mobile,PIN,null,null from UserNotVerified where Mobile=p_Mobile;
always results--- "result 00" ---why?
if i remove this
insert into Userverified (UserID, Mobile, PIN,uname,unameid)
select NextUserID(),Mobile,PIN,null,null from UserNotVerified where Mobile=p_Mobile;
works fine.
im using PhpMyAdmin and new with MYsql.
code attached here as---
CREATE procedure test
(
p_Mobile varchar(13),
p_LastOTP varchar(6)
)
begin
if ((select count(*) from UserVerified where mobile=p_Mobile)=0)
then
insert into Userverified (UserID, Mobile, PIN,uname,unameid)
select NextUserID(),Mobile,PIN,null,null from UserNotVerified where Mobile=p_Mobile;
if((select count(*) from uwallet where mobile=p_Mobile)=0)
then
insert into UserWallet (WalletID,Mobile,JoinAmount,WinAmount,ReferAmount,TotalAmount,DateModified)
select nextwalletid(),p_Mobile,0,0,0,0,now();
end if;
select 1 as result;
else
select '00' as result;
end if;
end;
Looking for help converting this mySQL Trigger, to TSQL.
CREATE TRIGGER IF not exists TF_WATCHLIST_PERSISTENCE_ADD_POSITION
AFTER INSERT ON TF_WATCHLIST_PERSISTENCE
FOR EACH ROW
WHEN NEW.WATCHLIST_POSITION IS NULL
BEGIN
UPDATE TF_WATCHLIST_PERSISTENCE SET
WATCHLIST_POSITION = (SELECT COUNT(*) - 1 FROM TF_WATCHLIST_PERSISTENCE WHERE WATCHLIST_USER = NEW.WATCHLIST_USER)
WHERE rowid = NEW.rowid;
END;
Thanks for all your help
I ended up with this.
CREATE TRIGGER TF_WATCHLIST_PERSISTENCE_ADD_POSITION
ON TF_WATCHLIST_PERSISTENCE
AFTER INSERT, UPDATE
AS
DECLARE #MyCursor CURSOR;
DECLARE #MyField_USER varchar(250);
DECLARE #MyField_ID varchar(250);
DECLARE #MyField_NewPos int
BEGIN
SET #MyCursor = CURSOR FOR
SELECT WATCHLIST_USER
, WATCHLIST_ID
FROM inserted
WHERE inserted.WATCHLIST_POSITION is null
OPEN #MyCursor
FETCH NEXT FROM #MyCursor
INTO #MyField_USER, #MyField_ID
WHILE ##FETCH_STATUS = 0
BEGIN
set #MyField_NewPos = (SELECT MAX(WATCHLIST_POSITION) + 1 FROM TF_WATCHLIST_PERSISTENCE WHERE WATCHLIST_USER = #MyField_USER)
print #MyField_NewPos
update TF_WATCHLIST_PERSISTENCE
SET WATCHLIST_POSITION = ISNULL(#MyField_NewPos,0)
WHERE WATCHLIST_USER = #MyField_USER
AND WATCHLIST_ID = #MyField_ID
AND WATCHLIST_POSITION IS NULL
Print #MyField_USER
Print #MyField_ID
FETCH NEXT FROM #MyCursor
INTO #MyField_USER, #MyField_ID
END;
END;
CLOSE #MyCursor
Try this:
CREATE TRIGGER TF_WATCHLIST_PERSISTENCE_ADD_POSITION ON TF_WATCHLIST_PERSISTENCE AFTER INSERT
AS
BEGIN
WITH DataSource AS
(
SELECT DS.WATCHLIST_USER
,COUNT(*) - 1 AS WATCHLIST_POSITION
FROM TF_WATCHLIST_PERSISTENCE DS
INNER JOIN inserted I
ON DS.WATCHLIST_USER = I.WATCHLIST_USER
WHERE inserted.WATCHLIST_POSITION is null
GROUP BY DS.WATCHLIST_USER
)
UPDATE TF_WATCHLIST_PERSISTENCE
SET WATCHLIST_POSITION = DS.[WATCHLIST_POSITION]
FROM TF_WATCHLIST_PERSISTENCE DS
INNER JOIN DataSource I
ON DS.WATCHLIST_USER = I.WATCHLIST_USER;
END
I suspect you are looking for a ranking function, or even a simple COUNT(*) per user? MySQL is rather poor in analytic, ranking or windowing functions so tricks like quirky updates or triggers are used to emulate them.
In SQL Server, you could return the number of records that match a single user in each row with COUNT() applied over the records that match a single user :
SELECT *, COUNT(*) OVER (PARTITION BY WATCHLIST_USER)
FROM TF_WATCHLIST_PERSISTENCE
No need for a trigger. You can use any aggregate with an OVER() clause.
If you want the rank according to some order, you can use one of the ranking functions like ROW_NUMBER() or `RANK(). If you want to calculate a row position per user based, eg on creation date you could write :
SELECT *, ROW_NUMBER(*) OVER (PARTITION BY WATCHLIST_USER ORDER BY CreationDate)
FROM TF_WATCHLIST_PERSISTENCE
If you have an incrementing ID you could use it to generate a row position per user
SELECT *, ROW_NUMBER(*) OVER (PARTITION BY WATCHLIST_USER ORDER BY ID)
FROM TF_WATCHLIST_PERSISTENCE
Most of the time, you don't need to store the row position. It's simple enough to add a ranking function to a query.
If you do need to store such a row position in a table, you could use a simple multi-row trigger
CREATE TRIGGER TF_WATCHLIST_PERSISTENCE_ADD_POSITION
ON TF_WATCHLIST_PERSISTENCE
AFTER INSERT, UPDATE
AS
update TF_WATCHLIST_PERSISTENCE
set WATCHLIST_POSITION =ROW_NUMBER() OVER (PARTITION BY WATCHLIST_USER ORDER BY ID)
FROM inserted
INNER JOIN TF_WATCHLIST_PERSISTENCE on inserted.ID=TF_WATCHLIST_PERSISTENCE.ID
Or
update TF_WATCHLIST_PERSISTENCE
set WATCHLIST_POSITION =ROW_NUMBER() OVER (PARTITION BY WATCHLIST_USER ORDER BY ID)
FROM inserted
INNER JOIN TF_WATCHLIST_PERSISTENCE
ON inserted.WATCHLIST_USER =TF_WATCHLIST_PERSISTENCE.WATCHLIST_USER
If you want to insert new entries for an existing user and recalculate all positions
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
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 ;