I need to run a script with update commands which do not specify the record IDs, so I know I must turn the flag of sql_safe_updates to OFF.
Yet, I need to restore the flag to its previous state.
Is there a way to hold the flag's value in a temporary parameter, then run my updates and restore it to its initial value?
(I will need to keep the script for deployment procedure, so I cannot change the flag's value manually every time it runs)
UPDATE:
That is about the script I have:
SET SQL_SAFE_UPDATES = 0;
UPDATE offensedb.offenses set Status = 6 , ClosingReason = 1 WHERE Status = 1;
SET SQL_SAFE_UPDATES = 1;
After examining a dump file of mysql I came across these commands:
SET #OLD_SQL_MODE=##SQL_MODE
-- some other sql commands there...
SET SQL_MODE=#OLD_SQL_MODE
So I figured out the answer to my question would be:
SET #SQL_SAFE_UPDATES=##SQL_SAFE_UPDATES;
UPDATE offensedb.offenses set Status = 6 , ClosingReason = 1 WHERE Status = 1;
SET SQL_SAFE_UPDATES = #SQL_SAFE_UPDATES;
Related
What i want thing is, i want to set the sql_mode variable as a local variable, not as a session or global variable. Reason to do that is i want to disapear the change of sql mode variable after one of query was executed. Below session and global are worked well, but this is not the what i want. Global one is kept the sql mode as a empty one forever. Session one is kept the sql mode as a empty one until connection close. I want thing is, keep the sql mode until a quarry is executed only.
mysql> set global sql_mode='';
mysql> set session sql_mode='';
mysql query :-
SELECT tc_exe_grp_num,tcs.tc_tc_id,tcs.tcs_id
FROM tc_exe_res tcer
INNER JOIN tcs tcs
ON tcs.tcs_id = tcer.tcs_tcs_id
WHERE tcs.tc_tc_id='1'
AND tcs.tc_tc_id='1'
GROUP BY tc_exe_grp_num
ORDER BY tc_exe_grp_num ;
got the idea from this article
please help me.
##sql_mode is session variable, not a local variable.
It is possible to retrieve the current setting of sql_mode, and save it in a user-defined variable, and then later set sql_mode back to the original setting.
For example:
-- save current setting of sql_mode in user defined variable
-- change sql_mode to desired setting
SET #SAVE_sql_mode = ##sql_mode ;
SET ##sql_mode = 'NO_ENGINE_SUBSTITUTION' ;
-- subsequent operations run under new setting of sql_mode
SELECT '...';
-- set sql_mode back to saved setting
SET ##sql_mode = #SAVE_sql_mode ;
I couldn't find a direct answer for this, but there is a solution,
First set the "sql mode" as a empty one and after quarry was executed set the "sql mode" with what previously had values, try it in below way,
set session sql_mode='';
SELECT tc_exe_grp_num,tcs.tc_tc_id,tcs.tcs_id FROM tc_exe_res tcer INNER JOIN tcs tcs ON tcs.tcs_id = tcer.tcs_tcs_id WHERE tcs.tc_tc_id='1' AND tcs.tc_tc_id='1' group by tc_exe_grp_num ORDER BY tc_exe_grp_num ;
set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
I got a project, which make insertions which inserting no values(not empty values) to the columns with NOT NULL and NO DEFAULT values.
I believed that is impossible to make insertion with missing required values, and it always throws an error: Field 'xxxx' doesn't have a default value. But as I see here mysql can be set to
sql-mode="NO_ENGINE_SUBSTITUTION"
I am confused, cause I think it is dangerous. And if I switch it OFF it will apply to all projects and it could be really bad. So what should I do? Is it possible to set the mode only for one mysql database while other databases will be on STRICT mode? What do you think about it? Is it an issue or not?
The sql-mode system variable is available at both global and session level. Which means either you have to set this for entire server or particular connection. So there is no way to configure this for subset of DBs at server level. However you can specify the sql mode when you are making the connection. So those connections will run in strict mode.
The solution that i propose is to made a trigger so when there is a no value it will insert a null value to that column
this is an example :
CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
END IF;
END;
So if somebody wants to know how it looks like in PHP/PDO for one concrete session:
$pdo = new PDO(
$dsn,
$username,
$password,
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode="NO_ENGINE_SUBSTITUTION"')
);
Not sure what session will be use for event execution. Will mysql always create new session or just reuse old while executing event ? what happens to user-defined variable ? what happen if different events use same user-defined variable( I know it is not good to use user-defined var here, but need to know what's the result).
some example code to explain a little bit:
CREATE EVENT myevent_a
ON SCHEDULE EVERY 1 minute
DO
Set #a = ...
UPDATE myschema.mytable SET mycol = #a;
CREATE EVENT myevent_b
ON SCHEDULE EVERY 1 minute
DO
Set #a = ...
UPDATE myschema.mytable SET mycol = #a;
will #a be read/write concurrently?
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;
Running this procedure causes MySQL (or phpMyAdmin) to freeze. I have to stop MySQL with from XAMPP command, which freezes and "is not responding" about 20 seconds before stopping. I believe this is caused by the delimiter command, which on it's own begins the problems. I have tried using a different delimiter ("//") to no effect.
DELIMITER $
CREATE TRIGGER coroner AFTER INSERT ON events
FOR EACH ROW BEGIN
UPDATE teams WHERE id = NEW.victim SET live = live-1;
UPDATE teams WHERE id = NEW.shooter SET score = score+points;
END
$
DELIMITER ;
As it turns out, phpMyAdmin has a field marked "delimiter:" below the SQL query box. Using it rather than the command solves the problem. Further research explains that "DELIMITER" is not a SQL command, but a command generally implemented by all SQL ui's.
the update command should:
update teams set live = live-1 where id = new.victim;
update teams where id = new.shooter set score = score+points;
the where after the set clause