Insert a record and also update existing records - mysql

hi there i was trying to right a Proc for a DataLoad when you want to insert records on a Table1 based on Table2
This is what i came of with
it has 2 condition
1) if the record does not exist create a new row of record
2) if the record already exist update the record based on keys
this is my proc need some help thanks
DECLARE #TableKey INT --(it is passed by the user proc param),
DECLARE #TableCount INT,
DECLARE #CLassKey INT,
SELECT #TableCount= COUNT(*) FROM Table1 WHERE Tablekey= #TableKey
INSERT INTO #CLassKey
SELECT Distinct c.PK_ClassKey FROM CLASS as c
INNER JOIN BOOK as B ON B.FK_ClassKey=C.PK_ClassKEy
IF ((SELECT COUNT(*) FROM #ClassKey) > 0 AND #TableCount= 0)--- this will check
BEGIN
Insert into NOTE
n.note
Select
c.note
FROM Class where c.FK_Note = n.PK_Note.
END
---- this will just insert for the first time..
How do i update it any idea as the records are only inserted for the first time put does not update using the same format thanks a lot

try this one
INSERT INTO table_name (id,col2,col3)
VALUES (value_id,value2,value3)
ON DUPLICATE KEY UPDATE
col2=value2,
col3=value3;

Related

Automatically add days to a column based on other table columns

I have a table A which has column NoOfDays, and another table B which has a column MyDate of type datetime and it is set to Default as "CURRENT_TIMESTAMP".
Now in table B, I want to add a new column (called ValidDate), which should AUTOMATICALLY store the sum value of (B.MyDate + A.NoOfDays)
For example, if B.MyDate has value of "2022-07-25 04:50:26" and A.NoOfDays has value of "60", then B.ValidDate should get the value of "2022-09-23 04:50:26"
What is the way in MySQL to set this new column value to store this summed value automatically.
Checked for existing threads, but found only this one which does not offer a solution to store, but to create a view output only.
MySQL - Add number of days to date in 3rd column automatically
For existing rows in table_b , use an update statement like UPDATE table_b set ValidDate=date_add(MyDate , interval + (select NoOfDays from table_a) day);
For new inserts, we can use a trigger to handle that. Here is the complete script written and tested in workbench:
create table table_a (NoOfDays int);
create table table_b(MyDate timestamp,ValidDate datetime);
insert table_a values(60);
DELIMITER //
drop trigger if exists auto_sum //
create trigger auto_sum before insert on table_b for each row begin
set new.ValidDate=date_add(new.MyDate , interval + (select NoOfDays from table_a) day);
end //
delimiter ;
insert into table_b (MyDate) values (default); -- The value of ValidDate is calculated in the trigger,so we only need to specify the value for MyDate.
Please try this:
CREATE TABLE TableA (NoOfDays INT);
INSERT INTO TableA VALUES(60);
CREATE TABLE TableB(MyDate DATETIME DEFAULT CURRENT_TIMESTAMP);
INSERT INTO TableB VALUES('2022-07-25 04:50:26');
ALTER TABLE TableB
ADD ValidDate DATETIME;
UPDATE TableB
SET ValidDate = date_add(MyDate, INTERVAL (SELECT NoOfDays FROM TableA) DAY);
If we test the result :
SELECT * FROM TableB;

Problem with inserting values after creating a TRIGGER

I am new in mysql and I am facing a problem I can't overcome, so I need your help.
I have created a trigger that looks like this:
delimiter //
CREATE trigger NEWBOOKTRIGGER138
after insert ON NEW_SALES
FOR each row
BEGIN
IF (SELECT COUNT(*) FROM NEW_SALES NS
INNER JOIN NEW_BOOKS NB ON NS.ISBN=NB.ISBN GROUP BY GENRE)>138 then
update GENRE set genre=GENRE|| "BEST.SELLER";
ELSEif (SELECT COUNT(*) FROM NEW_SALES NS
INNER JOIN NEW_BOOKS NB ON NS.ISBN=NB.ISBN GROUP BY GENRE)<=138 then
update GENRE set genre= GENRE;
end if;
END;//
In order to change the genre title(in table new_books) into genre BEST.SELLER if a book appears more than 138 times in the new_sales table, let's say.
I get a message that the trigger was successfully created.
The problem is that when I try to insert a tuple in new_books table (in order to see if the trigger actually works) I get an Error code 1242: Subquery returns more than 1 row.
I try to insert the tuple this way:
INSERT INTO NEW_SALES(ISBN,cid)
VALUES ("6666666666666",555);
When I drop the trigger the above insert command works just fine,
But how can I test the functionality of the trigger if I can't insert a new tuple?
Thank u in advance guys.
Kostas
You seem to be updating the wrong table, I assume you want to update the genre column in the NEW_BOOKS table. And it only seems necessary to update it for the book that you're currently inserting, which is NEW.isbn, so you don't need a JOIN.
Also, MySQL doesn't use || for concatenation, it uses the function CONCAT().
CREATE trigger NEWBOOKTRIGGER138
after insert ON NEW_SALES
FOR each row
IF (SELECT COUNT(*) FROM NEW_SALES WHERE isbn = NEW.isbn) > 138
THEN
UPDATE NEW_BOOKS AS b
SET genre = CONCAT(genre, "BEST.SELLER")
WHERE b.isbn = NEW.isbn;
You don't need an ELSEIF statement, since you don't need to do anything to keep the genre the same.

MySQL if condition inside a trigger

I have 2 tables, lets name it table A and table B, every time something is inserted in the table A I want some of the data (id, name, comment) automatically inserts also in the table B but only if there is no raw in table B with the same name.
Example:
If I insert OBJECT1 in A with values:
id=1, colour=2, name=example, price=5€, comment="blablabla"
it should be inserted in the table B a row with this values:
id=1, name=example, comment="blablabla"
but if then I insert OBJECT2 in A with values:
id=2, colour=5, name=example, price=10€, comment="aaa";
nothing should happen in the table B, because there is already a row in table B with name=example.
This is my code:
CREATE TRIGGER mytrigger
BEFORE INSERT ON tablea
IF NOT EXISTS (SELECT * FROM tableb WHERE tableb.name = NEW.name)
THEN
INSERT INTO tableb (id, name, comment)
VALUES (NEW.id, NEW.name, NEW.comment)
END IF
And this is the error I receive:
You have an error in your SQL Syntax...
I also tried adding BEGIN and END at the starting and end of the definition, also tried with END instead of END IF, also tried BEGIN instead of THEN
Does someone know what am I doing wrong?
In PL/SQL, you can't put an EXISTS() in an IF statement.
So please try this:
CREATE OR REPLACE TRIGGER mytrigger
BEFORE INSERT ON tablea REFERENCING NEW AS NEW
FOR EACH ROW
declare cnt integer;
BEGIN
SELECT count(*) into cnt FROM tableb WHERE tableb.name = :NEW.name;
IF cnt >0
THEN
INSERT INTO tableb (id, name, comment)
VALUES (:NEW.id, :NEW.name, :NEW.comment)
END IF
END;

Getting information from a third table in a MySQL trigger

What I want to do is similar to this, except the action is an insert not an update. I will use the same example used in that question, modified for my context;
I want to do something like this:
CREATE TRIGGER au_TableA AFTER UPDATE TableA
FOR EACH ROW BEGIN
INSERT INTO TableB (cID, points) VALUES (NEW.cID, TableC.points);
END
cID is present in TableA and TableC. Because it's not an UPDATE I can't do a JOIN like in the other question (right?). Is there any way to get the data from TableC INSERTED into TableB here?
If I understand your question correctly, this should be the trigger that you need:
CREATE TRIGGER au_TableA AFTER UPDATE TableA
FOR EACH ROW
BEGIN
INSERT INTO TableB (cID, points)
SELECT TableC.cID, TableC.points
FROM TableC
WHERE TableC.cID = NEW.cID;
END
You don't need a JOIN in this case, but you could use the syntax INSERT INTO ... SELECT

track multiple identical entries

I got a table that I am allowing identical entries (duplicates, triplecates etc.) but I also got a column that I want everytime that an entry is being made to be updated with the how many times that entry exists.
So I thought to write a trigger, I can already find the duplicate entries by doing
select count(pid) from items group by pid having count(*);
but the thing is that this query returns less columns that the orinal table (cause there are many duplicates)
so there is no 1 to 1 relation between the query and the table so I can use update. How could I modify this to get the desired result
thank you in advanced.
The main problem that you'll face here is that MySQL will not allow you to modify the items table using an AFTER INSERT ... trigger following a modification to the items table itself (think of how this could lead to a circular reference).
One solution is to store the counts in a separate table altogether (say items_pid_info). The primary key of this table would be pid and it is this table that would be updated by the triggers on the main items table. When you need to access the pidCount for a given pid simply join onto this table and you will have up-to-date pid counts for your given pid. Hence:
create table items_pid_info
(pid int unsigned not null primary key,
pidCount int unsigned not null);
Now create INSERT, UPDATE and DELETE triggers on your items table to update the items_pid_info table:
DELIMITER &&
CREATE TRIGGER items_pid_count_ins_trg
AFTER INSERT ON items
FOR EACH ROW BEGIN
DECLARE c int;
set c := (select count(*) from items im where im.pid = NEW.pid);
insert into items_pid_info values (NEW.pid,c) on duplicate key update pidCount = c;
END&&
CREATE TRIGGER items_pid_count_upd_trg
AFTER UPDATE ON items
FOR EACH ROW BEGIN
DECLARE c int;
set c := (select count(*) from items im where im.pid = NEW.pid);
insert into items_pid_info values (NEW.pid,c) on duplicate key update pidCount = c;
END&&
CREATE TRIGGER items_pid_count_del_trg
AFTER DELETE ON items
FOR EACH ROW BEGIN
DECLARE c int;
set c := (select count(*) from items im where im.pid = OLD.pid);
insert into items_pid_info values (OLD.pid,c) on duplicate key update pidCount = c;
END&&
DELIMITER ;
Hope this helps.