mySQL TRIGGER error code 1064 - mysql

USE test;
CREATE TRIGGER AvgUpdateTrigger AFTER INSERT ON test.score
FOR EACH ROW
BEGIN
INSERT INTO test.average (test.average.TestID, test.average.TestAvg)
(SELECT test.score.TestID, avg(test.score.ScoreValue) FROM test.score GROUP BY test.score.TestID)
ON DUPLICATE KEY
UPDATE test.average.TestAvg = (SELECT avg(test.score.ScoreValue) FROM test.score WHERE test.score.TestID = test.average.TestID GROUP BY test.score.TestID);
END;
im trying to update one table(average) when another one gets changed(score)
it is telling me to add a semicolon but as you can see there is one there allready

If a trigger (or any stored procedure) contains only one statement, you don't need BEGIN and END:
CREATE TRIGGER AvgUpdateTrigger AFTER INSERT ON test.score
FOR EACH ROW
INSERT INTO test.average (TestID, TestAvg)
SELECT test.score.TestID, avg(test.score.ScoreValue)
FROM test.score
GROUP BY test.score.TestID
ON DUPLICATE KEY UPDATE
test.average.TestAvg = VALUES(TestAvg);
I also replaced the subquery with VALUES(TestAvg), since this value has already been selected.

Related

Create My sql trigger for After insert , update another table column using inserted record [duplicate]

What is the error in the following code. I am executing in mysql
CREATE TRIGGER tg_order_insert
BEFORE INSERT
ON `order` FOR EACH ROW
BEGIN
INSERT INTO `grocery`.`order_seqid` VALUE(NULL);
SET NEW.order_id = CONCAT('#GNC', LPAD(LAST_INSERT_ID(),3,'0'));
END;
Grocery is the database and order_seqid and order are 2 table.
order_seqid is a table with only 1 attribute if type int and auto increment.
Am trying to put a prefix on the id which we insert into order table.
I am getting 2 errors in INSERT INTO..... and END; line
Did you declare a delimiter before your trigger definition? Something like
DELIMITER //
CREATE TRIGGER tg_order_insert
BEFORE INSERT
ON `order` FOR EACH ROW
BEGIN
INSERT INTO `grocery`.`order_seqid` VALUE(NULL);
SET NEW.order_id = CONCAT('#GNC', LPAD(LAST_INSERT_ID(),3,'0'));
END
//
Because if you don't, then MySQL thinks you're trying to end your trigger definition when it sees that first ; and calls syntax error.

SQL trouble with insert in if statement

DROP PROCEDURE IF EXISTS kund2orderNew;
DELIMITER ;;
CREATE PROCEDURE kund2orderNew(kundId2 INT)
BEGIN
IF kundId2 <> (SELECT kundId FROM kund2order) THEN
INSERT INTO kundOrder VALUES ();
INSERT INTO kund2order VALUES (kundId2, (SELECT id FROM kundOrder));
END IF;
END
;;
DELIMITER ;
Alright am I doing something wrong here? What im trying to do is to check if kundId is in the kund2order, if its not then what I want to do is create a new row in the kundOrder table that just uses the default values and then take the recently created id from that row in the kundOrder and put it inside the new row in kund2order (together with kundId).
For some reason it just gives me (node:18328) UnhandledPromiseRejectionWarning: Error: ER_BAD_NULL_ERROR: Column 'kundId' cannot be null
I am a bit confused as to what the problem is, both tables are empty after I have called this procedure. Is the problem my if statement or is it something else?
That's not the correct way to check if an ID is already in the table. When you use a SELECT query as an expression, it has to return just one row. You can use:
IF NOT EXISTS (SELECT * FROM kund2Order WHERE kundId = kundId2) THEN
And if you want to insert the auto-increment of the row that was just inserted into kundOrder, you should use LAST_INSERT_ID():
INSERT INTO kund2order VALUES (kundId2, LAST_INSERT_ID());

MySQL BEFORE INSERT trigger to turn duplicate primary keys inserts into updates

I'm trying to execute this query in a database through phpmyadmin
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to
END IF;
END
But phpmyadmin gives me the following error:
MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7
Two questions:
What's wrong with my script?
After a BEFORE INSERT trigger, Will INSERT operation be performed? In case it doesn't I will have to remove INSERT INTO SharingEvents (SELECT * FROM NEW);
I solve it with the following code:
delimiter $$
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to;
end if;
END$$
The problem was the delimiter.
Even so, my trigger doesn't work. When the application inserts duplicated primary keys MySQL throws the following error:
#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Use exists:
if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then
insert into sharingevents (shared_note_id,shared_to,permission_level)
values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level);
end if;
Or, better yet, add a unique index on sharingevents(shared_note-id, shared_to) and then use:
insert into sharingevents (shared_note_id, shared_to, permission_level)
values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level)
on duplicate key update shared_note_id = values(shared_note_id);
This will ignore any updates where the pairs already exist in the table. No if required.
count(shared_note_id, shared_to) is invalid syntax. You can only put multiple column names inside COUNT() when you use count(DISTINCT ...). In your case, you don't need to put column names at all, just use COUNT(*) to count the number of rows matching the condition.
See count(*) and count(column_name), what's the diff? for more information about when you should put column names in COUNT()
Unfortunately, fixing the syntax errors won't really solve your problem, because you can't use a trigger to make a change to the same table. From the FAQ:
Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
You'll need to recode the callers to use INSERT ... ON DUPLICATE KEY UPDATE, or something equivalent, to accomplish this.

How can I Update column value to Old value plus New value from other table using Trigger?

How can I Update column value to Old value plus New value from other table using Trigger if that value has already have an entry?
What I wanted is something like the following. Notice the bold and italicized part.
DELIMITER$$
CREATE TRIGGER trigger_name AFTER INSERT
ON table_one FOR EACH ROW
BEGIN
INSERT INTO table_two(clmn_id, clmn_one) VALUES(NEW.clmn_id_fk,NEW.clmn_a)
ON DUPLICATE KEY UPDATE clmn_one = VALUES(clmn_one + NEW.clmn_a);
END$$
DELIMITER;
Try removing the keyword VALUES from the ON DUPLICATE KEY:
DELIMITER$$
CREATE TRIGGER trigger_name AFTER INSERT
ON table_one FOR EACH ROW
BEGIN
INSERT INTO table_two(clmn_id, clmn_one) VALUES(NEW.clmn_id_fk,NEW.clmn_a)
ON DUPLICATE KEY UPDATE fine_amount = clmn_one + NEW.clmn_a;
END$$
DELIMITER;
Looks like you need a select statement first, to check if it already exists. If so, set variables to current values, then run an update that combines the old values (variables) and new values. If the record doesn't already exist, run insert statement with current values.

MySQL - Trigger to delete previous record

I'm trying to create a trigger that will allow only one record in a database, so it would delete any previous records.
But currently, it doesn't allow me to insert anything it, because it's instantly deleted.
DELIMITER $$
CREATE TRIGGER test_insert
BEFORE INSERT ON test
FOR EACH ROW BEGIN
DELETE FROM test WHERE id = NEW.id - 1;
END$$
How would I delete a previously (or all previous) inserted record?
"But currently, it doesn't allow me to insert anything it, because it's instantly deleted."
Acutally, when you do an INSERT, the execution of your trigger should be throwing exception:
Error Code: 1442
Can't update table 'test' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger.
(Unless something is radically different in a newer version of MySQL.)
The operation you want to perform (i.e. deleting rows from the same table you are inserting into) cannot be done in a MySQL trigger.
You could use a combination of a UNIQUE KEY and a BEFORE INSERT trigger to prevent more than one row from being inserted. The BEFORE INSERT trigger could set the value of the column that has a unique
key on it to be a static value, then the INSERT statement would throw a duplicate key ("Duplicate entry") exception.
Then, you could use an INSERT ... ON DUPLICATE KEY UPDATE ... statement to update the values of columns other than the unique id, e.g.
CREATE TRIGGER `test_insert` BEFORE INSERT ON test
FOR EACH ROW BEGIN
SET NEW.id := 1;
END
ALTER TABLE test ADD UNIQUE KEY (id);
INSERT INTO test (somecol) VALUES ('someval')
ON DUPLICATE KEY UPDATE somecol = VALUES(somecol) ;
To do that you first need to find some value at which you want to delete all and insert for. This way you don't need a trigger, you simply delete all previous cases and then add a new row. Unless for some reason unexplained from your code you would need a trigger a simple solution in your loop could work Like:
$query = mysql_query("DELETE FROM test WHERE id = NEW.id -1");
$new_id = $new.id -1;
$query2 = mysql_query("INSERT INTO test VALUES('$new_id','$var1','$var2'));