I have an issue which i'm hoping someone out there will be able to assist.
I'm trying to write a trigger which takes the datetime stamp and puts just the date into a new column. But likewise, also if a value in a different column is equal to x, then replace it with y.
I can get individual statements to work (i.e if I have just the date code or the replacement code individually it works fine), but I can't get them to both work in the same trigger.
SET NEW.date = LEFT(NEW.entrydate, 10);
IF
(NEW.connect_ip = "1.2.3.4")
THEN SET
NEW.connect_ip = "0.0.0.0";
END IF
Multi-statement triggers need BEGIN and END around their "body", and usually DELIMITER overridden around their declaration.
Example/Template:
DELIMITER $$
CREATE TRIGGER [blah blah]
BEGIN
[do stuff]
END$$
DELIMITER ;
Alternatively, for your specific case, I noticed an answer the other day with a possiblity I had overlooked; you can set multiple things in a SET statement:
SET NEW.date = LEFT(NEW.entrydate, 10)
, NEW.connect_ip = IF(NEW.connect_ip = "1.2.3.4", "0.0.0.0", "1.2.3.4")
;
Related
i have a site where i can update the date of a row, by clicking on the table, when i change the value and press enter its updated in the database.
what i want: in the date field. just to type mm/dd (e.g. 05-20) press enter.
then my trigger should:
CREATE TRIGGER before_transactions_update
BEFORE UPDATE
ON Transactions FOR EACH ROW
BEGIN
-- variable declarations
declare inputDate integer;
-- trigger code
-- get month and day
-- LEFT(inputDate, 2); RIGHT(inputDate, 2)
-- STR_TO_DATE('2015,MONTH(LEFT),DAY(RIGHT)','%Y,%m,%d');
SET INSERTED.date = 2015-month-day-00-00-00;
END;
this is what i've "tried" or at least as far as i have come on my own. MySQL workbench stops me at the declaration of my var, it tells me i need a semi colon after declaration, which i dont seem to need
So i've been googling for hours and i've met a dead end as a newbie in MySQL so could anyone fill out the blanks or point me in the right direction,
that would be great
You can not pass the input parameter directly into the trigger unless that input is somewhere in the update statement
Also you need to specify a delimiter in the trigger.
If your input values are always in the form m-d as you shown in the example and the year is the current year then the following trigger should do the job.
delimiter //
CREATE TRIGGER before_transactions_update BEFORE UPDATE
ON Transactions
FOR EACH ROW
BEGIN
if length(new.date) = 5 then
set new.date = concat(year(curdate()),'-',new.date);
end if ;
END;//
delimiter ;
I'am developing a small project with PHP and MySql on a Wamp server. I just discovered the wonderful principle of SQL triggers. Hum... well. It would be wonderful if I could use it.
Indeed I have a problem with the following script:
BEGIN
SET #liste = NEW.reponse
WHILE LEN(#liste) > 0
BEGIN
IF PATINDEX('%,%',#liste) > 0
BEGIN
SET #choix = SUBSTRING(#liste, 0, PATINDEX('%,%', &liste))
INSERT INTO resultat (referendum, choix) VALUES (NEW.id, #choix)
SET #liste = SUBSTRING(#liste, LEN(#choix + ',') + 1, LEN(#liste))
END
END
END
I would like to execute this trigger after the insertion of a record in table "Referendum". In this table, there is a field "reponse" which contains the different possible answers. This field contains this kind of data: "Yes,No,I don't know". For each new question, I want to insert a new record in table "Resultat" per possible answer.
In my example, three new records: one for Yes, one for No and one for I don't know.
My code comes from an example on the internet but it doesn't work properly. SQL returns a syntax error with message "While_Sym expected"...
I tried to add semicolon following what I found on the internet but no way...
I guess you need something like this:
CREATE TRIGGER mytrigger AFTER INSERT
ON Referendum FOR EACH ROW
BEGIN
DECLARE cnt int;
DECLARE str varchar(100);
Set cnt = CHAR_LENGTH(NEW.reponse)
- CHAR_LENGTH(Replace(NEW.reponse,',','')) +1;
WHILE cnt > 0 DO
Set str = SUBSTRING_INDEX(
SUBSTRING_INDEX( New.reponse,',', -cnt)
,',',1);
INSERT INTO resultat (referendum, choix)
VALUES (NEW.id, str);
Set cnt = cnt - 1;
END WHILE;
END;
Demo: http://sqlfiddle.com/#!2/c7321/1
Some thoughts:
There are no PATINDEX nor LEN functions in MySql, they come from SQL Server.
Most functions are not standard in SQL, one shouldn't expect that something that works on database X should also work on database Y (and vice versa)
You always need to check the manual.
There is difference in MySql between #variable and variable - they are not the same (opposite to SQL Server where there is only one kind of variables --> #variable).
Please refer to documentation to learn about #user_definied_variables and local_variables
http://dev.mysql.com/doc/refman/5.7/en/user-variables.html
http://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
Depending on your client software you may need to use also DELIMITER xx command, for example in mysql console client or MySql-Workbench you need something like this to create a trigger without syntax errors:
DELIMITER $$
CREATE TRIGGER mytrigger AFTER INSERT
ON Referend ......
......
......
END;
$$
DELIMITER ;
I have to make a trigger that takes a current_timestamp + minutes and says that if its older than the current_timestamp it should be INSERT INTO a new table.
I have been playing around with this for 8 hours now but can't seem to make it work. Anyone have an solution for this?
This was my idea:
DELIMITER //
CREATE TRIGGER create_comment
AFTER UPDATE ON aflaesning
FOR EACH ROW
BEGIN
IF (TIME_TO_SEC(OLD.forventetSlut) < TIME_TO_SEC(NEW.aktuelSlut-900)) THEN
INSERT INTO aflaesningkommentar(aflaesningaflaesning,aflaesning_id) VALUES('That was too late', NEW.aflaesnings_id);
END IF;
END;
DELIMITER//
It takes the TIMESTAMP (ExpectedEnd) from the table Loadings and have to put the row into the table delayedLoadings if the timestamp is older than minutes. BUT it makes an error on the END IF//
Thanks in advance
The primary problem is the delimiter you are using. You should use a semi-colon after END IF, and then use the // after the END at the end of your trigger (which is also missing).
Also, unrelated to the error, I think you're conditional is wrong. You probably want to do this:
IF (TIME_TO_SEC(OLD.forventetSlut) < TIME_TO_SEC(NEW.aktuelSlut)-900) THEN
Instead of this:
IF (TIME_TO_SEC(OLD.forventetSlut) < TIME_TO_SEC(NEW.aktuelSlut-900)) THEN
So something like this:
DELIMITER //
CREATE TRIGGER create_comment
AFTER UPDATE ON aflaesning
FOR EACH ROW
BEGIN
IF (TIME_TO_SEC(OLD.forventetSlut) < TIME_TO_SEC(NEW.aktuelSlut)-900) THEN
INSERT INTO aflaesningkommentar(aflaesningaflaesning,aflaesning_id) VALUES('That was too late', NEW.aflaesnings_id);
END IF;
END //
DELIMITER;
Try changing your IF condition to:
IF (TIME_TO_SEC(OLD.forventetSlut) - TIME_TO_SEC(NEW.aktuelSlut) < -900) THEN
Also, change the semi-colon after the last END to //.
Lastly, try removing all whitespace from your source and replacing with space and newline. Mysql can't handle tab characters in trigger source.
New to MySql triggers, just learning.
CREATE TRIGGER MyTrigger
AFTER UPDATE ON MyTable
FOR EACH ROW
BEGIN
IF (new.field1 < 0 or new.field1 > 5) THEN
UPDATE new SET new.field1 = old.field1;
END IF;
END;
The goal is to keep the value of field1 the same, if the update puts it outside the range.
However, instead it sets it to 0. What am I doing wrong? How should this code look?
Here is an example that should hopefully get you started:
DELIMITER ~
CREATE TRIGGER `so_13547992_trigger`
BEFORE UPDATE ON `so_13547992`
FOR EACH ROW BEGIN
IF ( NEW.`field1` < 0 OR NEW.`field1` > 5 ) THEN
SET NEW.`field1` = OLD.`field1`;
END IF;
END;
~
Why would it work better? Well first of all your example trigger is recursive, you can't update the same table in a trigger that was triggered by an update.
Second, the new in your UPDATE statement is not a table name, you need to specify one explicitly.
It doesn't appear to be a legit trigger at all, doesn't your server complain when you try to create it? Can you perhaps show actually SHOW CREATE TRIGGER `your_trigger`; to make sure that it's really created and looks like you pasted it above?
Even if your example would would work, you're trying to do an unconstrained update on all rows of your table, not on the ones you're trying to update, you should have a WHERE clause; again, given that issue one and two are taken care of.
I am seeking a short term solution while I work out why a synchronisation is setting one field wrong in a table
I prepared a trigger and would welcome some comment on it, and any necessary corrections or better strategies.
CREATE TRIGGER urlcorrect AFTER INSERT ON sym_node
FOR EACH ROW BEGIN
IF NEW.sync_url= 'http://wrongaddress' THEN
UPDATE sym_node SET sync_url= "http://123.456.7.89:1234/etc";
END IF;;
END$
delimiter;
thanks
David
Your trigger is wrong in various ways.
First of all, I think you want a BEFORE trigger so that you can fix the row before it gets into your table.
Secondly, this:
UPDATE sym_node SET sync_url= "http://123.456.7.89:1234/etc";
would update every sync_url in the sym_node table and that's not what you want. And I don't think MySQL will let you UPDATE a table inside a trigger on that table (someone correct me if I'm wrong on this please). Also, you should be using single quotes for string literals even though MySQL will let you use double quotes, don't pick up bad habits from MySQL lax behavior. You want to:
set new.sync_url = 'http://123.456.7.89:1234/etc';
Putting all that together, you get this:
delimiter $
create trigger urlcorrect before insert on sym_node
for each row begin
if new.sync_url = 'http://wrongaddress' then
set new.sync_url = 'http://123.456.7.89:1234/etc';
end if;
end;
$
delimiter ;