MySQL disable all triggers - mysql

For test correctness of query I need disable all triggers in db.
I see that in information_schema exists table TRIGGERS.
Is possible temporarily disable all triggers using this table?
E.g. like:
update TRIGGERS set TRIGGERS_SCHEMA='myschema_new'
where TRIGGERS_SCHEMA='myschema'
and after finish all test return all triggers like:
update TRIGGERS set TRIGGERS_SCHEMA='myschema'
where TRIGGERS_SCHEMA='myschema_new'
May be this can corrupt db or after triggers will not works? I didn't found about it in documentation.

You can't disable triggers directly and I wouldn't recommend doing what you're suggesting but you could have your trigger check if a variable (in my example below #disable_triggers) is NULL before executing the trigger's content. For example:
Query:
SET #disable_triggers = 1;
// Your update statement goes here.
SET #disable_triggers = NULL;
Triggers:
IF #disable_triggers IS NULL THEN
// Do something use as the trigger isn't disabled.
END IF;

It is not possible to 'disable' triggers in mysql, however a trick that can be used to get around this
Add a condition in your triggers like:
if (DISABLE_TRIGER <> 1 ) then
#trigger body
end if;
and than if you want to disable triggers on import just:
SET #DISABLE_TRIGER = 1;
do imports
SET #DISABLE_TRIGER = 0;

Related

Do I need to duplicate my triggers to cover the before insert and before update scenarios?

I created some triggers to make some simple validations. I covered the before insert scenario, for example:
CREATE TRIGGER TR_before_insert_login
BEFORE INSERT ON login
FOR EACH ROW
BEGIN
IF (CHAR_LENGTH(NEW.password) < 4 OR CHAR_LENGTH(NEW.password) > 10) THEN
SIGNAL SQLSTATE '42000'
SET MESSAGE_TEXT = 'password must be between 4 e 10 characters';
END IF;
......
But if the user performs an update I can't prevent it from entering incorrect data. Do I need to create a before update and duplicate my validation code or there is a better way to do this.
Why don't put the logic (your validation code) into procedure and execute it inside the separate triggers (insert/update).
-- pseudo code
create procedure PASSWORD_VALIDATION(_psswd) { /* validation */ };
create trigger table_ub BEFORE UPDATE { CALL PASSWORD_VALIDATION(NEW.password);};
create trigger table_ib BEFORE INSERT { CALL PASSWORD_VALIDATION(NEW.password);};
Thus, your validation code is not duplicated.
ALTER TRIGGER [dbo].[trigger_name]
ON [dbo].[table_name]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
'your code here'
END
you can use structure like this to call same trigger for insert,update and delete

SQL Disabling trigger

I need to create a stored function which disables triggers on demand.
At first I have a parameter #disable_triggers which can I set to "all" or to specific trigger name. In the trigger I would have a variable which I assign to procedures return value and if it's true I don't execute trigger code. So in procedure I need to somehow handle the case with specific trigger name.
CREATE PROCEDURE `DisableTriggers`()
BEGIN
IF(#disable_triggers = 'all') THEN
RETURN 1;
END IF;
IF (#disable_triggers CONTAINS 'Specific trigger name') THEN
Return true to disable specific trigger. <<-- how to return it here.
END IF;
END
So the question I ask is how to handle the case with specific triggers what to return.
In general there is no way to disable triggers in MySQL/MariaDB.
You can only delete triggers and re-create them later but be aware of MDL locks if you have high loaded environment.
Still you have an option to do some tricks with session variables like MySQL disable all triggers

Update trigger disables functionality of database

I am trying to add a trigger to my SQL DB from phpMyAdmin.
When applying the trigger:
CREATE TRIGGER `download_url` AFTER INSERT ON
`tbl_files` FOR EACH ROW UPDATE tbl_files SET
download = CONCAT('http://website/', url)
WHERE 1
When trying to upload a file, I get no results; if I remove the trigger it functions properly. I need the download column to update with the prefix [http://website/] and value [url].
Thank you!!!
You can use a considerably simpler approach - instead of having an AFTER INSERT trigger, use a BEFORE INSERT trigger and manipulate the incoming row before writing it to the table. You can use the special variable NEW to reference this new row:
CREATE TRIGGER download_url
BEFORE INSERT ON tbl_files
FOR EACH ROW
SET NEW.download = CONCAT('http://website', NEW.url);
END;

MySql - trigger doesn't run as expected

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.

Does MySQL permit callbacks in C such that when a change happens, I can be notified?

Does MySQL permit callbacks in C such that when a change happens in the database, like an insert, that is performed by a different program or by the user at the command line, I can be notified?
I am guessing that it doesn't, because mysqlclient is a library, not a running thread. But I may as well ask.
Create a trigger like so.
DELIMITER $$
CREATE TRIGGER ad_mytable_each AFTER DELETE ON MyTable FOR EACH ROW
BEGIN
#write code that trigger After delete (hence the "ad_" prefix)
#For table MyTable (The _MyTable_ middle)
#On each row that gets inserted (_each suffix)
#
#You can see the old delete values by accesing the "old" virtual table.
INSERT INTO log VALUES (old.id, 'MyTable', old.field1, old.field2, now());
END$$
DELIMITER ;
There are triggers for INSERT, DELETE, UPDATE
And they can fire BEFORE or AFTER the action.
The trigger BEFORE the action can cancel the action by forcing an error, like so.
CREATE TRIGGER bd_mytable_each BEFORE DELETE ON MyTable FOR EACH ROW
BEGIN
#write code that trigger Before delete (hence the "db_" prefix)
declare DoError Boolean;
SET DoError = 0;
IF old.id = 1 THEN SET DoError = 1; END IF;
IF (DoError = 1) THEN SELECT * FROM Table_that_does_not_exist_to_force_error;
#seriously this example is in the manual.
END$$
DELIMITER ;
This will prevent deletion of record 1.
A before UPDATE Trigger can even change the values updated.
CREATE TRIGGER bu_mytable_each BEFORE UPDATE ON MyTable FOR EACH ROW
BEGIN
IF new.text = 'Doon sucks' THEN SET new.text = 'Doon rules';
END$$
DELIMITER ;
Hope you'll be Trigger happy.
MySQL's triggers allow you to hook into insert/update/delete queries and do something additional. You could log them in a separate table, for example.
Well you could attach a trigger to user defined function, and have it call an external program, that would then notify your code..
http://dev.mysql.com/doc/refman/5.0/en/faqs-triggers.html#qandaitem-B-5-1-10
You can use triggers combined with UDFs (user defined functions) so that the corresponding action on the database executes a trigger that calls a C/C++ function.
Just consider that this mechanism runs your code inside the mysql server process, not in the client side.