Error #1193 MySql, insert trigger - mysql

CREATE TRIGGER `UpdateId`
BEFORE INSERT ON `comments`
FOR EACH ROW
set #vid=(select MAX(comments.id) from comments)+1;
set new.id=#vid;
this query gives me an error #1193 saying id variable is unknown.
Everybody that seemed to have a similar problem was not putting the 'new' clausole before the variable, but in my case it still doesn't work. The 'new' clausole doesn't get highlighted when I type it, it looks like it is not a special keyn word but a normal word instead.

From https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html, it looks like you might need to either use just one set statement or use a begin ... end construct. My hunch is that the create trigger statement ends at the first semi-colon, and then MySQL doesn't know what you're talking about when it gets to new.id=#vid;.
CREATE TRIGGER `UpdateId`
BEFORE INSERT ON `comments`
FOR EACH ROW
set
#vid=(select MAX(comments.id) from comments)+1,
new.id=#vid;
OR
delimiter //
CREATE TRIGGER `UpdateId`
BEFORE INSERT ON `comments`
FOR EACH ROW
begin
set #vid=(select MAX(comments.id) from comments)+1;
set new.id=#vid;
end;//
delimiter;

Related

MySQL Trigger update a 'modifiedDate' column not working properly

I have a special requirement where I need to automatically update a 'modifiedDate' column's datetime value to NOW(), IF:
Value provided is null
Value provided is the same as what it was before the update
BUT
If value provided is any other date string, then update column with value.
So, I've setup this trigger, but something's now quite right with it:
CREATE TRIGGER `tr_users_updateModDateOnUpdate` BEFORE UPDATE ON `tbl_users`
FOR EACH ROW IF (OLD.date_modified <> NEW.date_modified) THEN
SET NEW.date_modified = IFNULL(NEW.date_modified, NOW());
ELSE
SET NEW.date_modified = NOW();
END IF
I can't see what's wrong with it... , but I'm getting strange behavior when testing with my web application.. So trying to see if the problem is with my trigger, or my php code...
Can anyone tell me if my Trigger code seems okay for my requirements above? Thanks a million!
Pat
Your trigger contains an IF statement, so it needs at BEGIN/END block. Also, the conditions do not seem to do what you want. Finally, you need to set the DELIMITER.
I think that this does what you want:
delimiter //
create trigger tr_users_update_mod_date_on_update
before update on tbl_users
for each row
begin
if new.date_modified is null or old.date_modified = new.date_modified then
set new.date_modified = now();
end if;
end;
//
delimiter ;

MySQL TRIGGER to INSERT BEFORE INSERT using SELECT, IF, etc

I am trying to write a trigger that combines an insert & select, I've found numerous topics online, but, none seem to relate to my exact problem, maybe I am missing something with my structure?
The aim of this is that on the event of a cancellation in our audit log, then I define a cancellation reason based on a series of business logic in another table, this logic is drawn together in a SELECT using CASE & subqueries.
I want to expand the following trigger that currently works and replace the SET cancellation_point='test' element with the SELECT query I just mentioned.
DELIMITER $$
CREATE
TRIGGER `cancellation_stage` BEFORE INSERT ON `log`
FOR EACH ROW
BEGIN
IF (NEW.status='cancel' AND NEW.type='0') THEN
INSERT INTO cancellation_stage
SET
id=NEW.id,
property_id=NEW.entity_id,
cancellation_date=NOW(),
cancellation_point='test';
END IF;
END;
$$
DELIMITER ;
I did try to construct this myself using various guidance from here, but, its just not working. I got this code to physically save as a trigger, but, it did not populate the data in the database (I have replaced my SELECT with a basic query example below):
DELIMITER $$
CREATE
TRIGGER `cancellation_stage` BEFORE INSERT ON `log`
FOR EACH ROW
BEGIN
DECLARE cancellation_point VARCHAR(255);
SET cancellation_point = ( SELECT * FROM x);
IF (NEW.transition='cancel' AND NEW.entity_type='property') THEN
INSERT INTO cancellation_stage
SET
id=NEW.id,
property_id=NEW.entity_id,
cancellation_date=NOW(),
cancellation_point=NEW.cancellation_point;
END IF;
END;
$$
DELIMITER ;
Any help would be greatly appreciated :)

How to create a Trigger within sql

I have been trying to create a Trigger, however my attempts have been unsuccessful. I seem to be getting an error (#1064), which I have no solution for. Can somebody explain or demonstrate any faults in the syntax.
Let me specify:
I have delivery_id as primary key in delivery table,
I also have delivery_id as a foreign key in entry_log table.
By comparing both id's(if true), will return a text referring to the output of the bit (either 0 or 1)
DELIMITER //
DROP TRIGGER IF EXISTS entry_trigger//
CREATE TRIGGER entry_trigger BEFORE INSERT ON entry_log
FOR EACH ROW
BEGIN
DECLARE #xentry VARCHAR(45)
DECLARE #inta bit
SET #inta = SELECT allowed
FROM delivery
WHERE delivery.delivery_id = entry_log.delivery_id;
CASE
when #inta = 0 then #xentry = 'Acces Denied'
when #inta = 1 then #xentry = 'Acces Allowed'
END CASE
INSERT INTO entry_log(entry_time,access_allowed) VALUES(now(),#xentry);
END
//
This is assuming that you use MySQL. In the body of the trigger you use
WHERE delivery.delivery_id = entry_log.delivery_id;
I think you want to compare to the entry_log entry that the trigger is running on, right? In that case you must use this syntax:
WHERE delivery.delivery_id = NEW.delivery_id;
see here for more examples.
UPDATE
I see that also you try to do an INSERT INTO entry_log within the TRIGGER. This will of course not work, because you would create an infinite recursive loop. Within the
body of the trigger you can do unrelated table access, but not into the table you are inserting. You can change the values to be inserted by the trigger by setting NEW.xyz = whatever
UPDATE 2
I doubt, that your CASE statement is correct. At least it must end with END CASE. You can use IF here, since you don't have many cases to address. If you must use CASE this post might help you: MYSQL Trigger set datetime value using case statement
UPDATE 3
I am not sure, but I think you need brackets around the variable setting statement. try this trigger definition:
DELIMITER //
DROP TRIGGER IF EXISTS entry_trigger//
CREATE TRIGGER entry_trigger BEFORE INSERT ON entry_log
FOR EACH ROW
BEGIN
SET #inta = (SELECT allowed
FROM delivery
WHERE delivery.delivery_id = NEW.delivery_id);
SET NEW.access_allowed = #inta;
SET NEW.entry_time = NOW();
END
//
Note, that this is written out of my head, so beware of syntax errors in my script.

MySQL IF Statement issue in a Trigger

So I am trying to create trigger that will only execute when a specific column within a table is updated. The table in question is track the column in question is track.track_hits. What I want to do is if that value changes then it inserts a value into a table called play_log. The insert should be the track_id from track and a timestamp.
The code I have done so far is below but it doesn't work, how can it be fixed?
CREATE TRIGGER pi_play AFTER UPDATE ON track
FOR EACH ROW
BEGIN
if :new.track_hits != :old.track_hits
then
INSERT INTO play_log (track_id,access_time)
VALUES (NEW.track_id, NOW())
end if;
END;
NEW and OLD do not need : in front. Also, when creating triggers, you may need to change the delimiter. If you don't change the delimiter, your create trigger statement may be terminated early.
Here's how I would do it:
delimiter |
create trigger pi_play after update on track
for each row
begin
if new.track_hits != old.track_hits then
insert into play_log(track_id, access_time) values (new.track_id, now());
end if;
end|
delimiter ;
Here's the fiddle showing it in action: http://sqlfiddle.com/#!2/3d99d/1 Notice that I changed the delimiter in the schema window to | instead of the default ;. Since SQL uses JDBC and JDBC doesn't take the command DELIMITER, I chose the delimiter.

MySQL trigger needs tweaking

I have a trigger that sets a datetime field in a table row when a new row is inserted. (Don't bother lecturing me that I could do this in the table definition, I have second datetime field that is using that functionality already and you can only do it with one column per table.)
This trigger works great for my purposes:
CREATE TRIGGER foobar_insert
BEFORE INSERT ON foobar
FOR EACH ROW SET NEW.created=NOW();
So whenever a new row is inserted, foobar.created gets set to the current time. This is great when I do something like:
INSERT INTO foobar (foo) VALUES ('bar');
The only problem with this is that if I want to explicitly set foobar.created in the insert statement, it gets overridden by the trigger.
So,
INSERT INTO foobar (foo,created) VALUES ('foo','2006-01-01 12:12:12');
results in foobar.created equaling the time of the insert, not the time specified in the insert statement.
So my question is: How can I change my trigger to only set foobar.created if it doesn't already have a value?
EDIT:
In response to james_bond below, here is what worked:
DELIMITER $$
DROP TRIGGER IF EXISTS foobar_insert$$
CREATE TRIGGER foobar_insert
BEFORE INSERT ON foobar
FOR EACH ROW
IF NEW.created IS NULL THEN
SET NEW.created=NOW();
END IF$$
DELIMITER ;
Note I had to include DELIMITER statements because the IF statement required an interior semicolon.
Test for NEW.created is NULL, if is set it's because you have set it in your insert statement,if it is NULL then it needs the current time as value, something like this will do the trick:
if NEW.created is NULL THEN
SET NEW.created = now();
end if