debugsqlMinor
Query works manually, not from stored procedure - Safe update error
Viewed 0 times
storederrorupdatequeryproceduremanuallyworkssafefromnot
Problem
I have a relatively simple update query that works fine when I manually execute it from a Mysql Workbench query window, but will not work when I call it as a stored procedure. The stored procedure in question:
The call to the stored procedure I'm using:
which returns
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
I would prefer not to disable safemode.
The manual query that works:
SalesGoals is a simple table:
It looks to me like when I call the stored procedure, it's ignoring my WHERE clause. I've been staring at this for a crazy long time and don't see anything wrong. What am I missing?
Thanks!
CREATE PROCEDURE `sp_UpdateGoal`(
IN UpdateGoalUserName varchar(45),
IN nGoalDate DATE,
IN nAmount DECIMAL(9,2),
IN nActiveGoal tinyint,
IN nOriginalAmount DECIMAL(9,2),
IN nChangeLog VarChar(100)
)
BEGIN
UPDATE
salesgoals
SET
Amount=nAmount,
OriginalAmount=nOriginalAmount,
`active`=nActiveGoal,
ChangeLog=concat(ChangeLog,"\r\n",now()," ",nChangeLog)
WHERE
salesgoals.username=UpdateGoalUserName
AND salesgoals.goalDate=nGoalDate;
ENDThe call to the stored procedure I'm using:
CALL sp_UpdateGoal( 'lauren', "2020-01-01",150000,1,150000,"Testing sp_UpdateGoal");which returns
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
I would prefer not to disable safemode.
The manual query that works:
UPDATE
salesgoals
SET
Amount=150000,
OriginalAmount=150000,
`active`=1,
ChangeLog=concat(ChangeLog,"\r\n",now(),'Testing manual query')
WHERE
username='lauren'
AND goalDate='2020-01-01';SalesGoals is a simple table:
CREATE TABLE `salesgoals` (
`username` varchar(45) NOT NULL,
`GoalDate` date NOT NULL,
`Amount` decimal(9,2) NOT NULL,
`ChangeLog` varchar(500) NOT NULL,
`Active` tinyint DEFAULT '1',
`OriginalAmount` decimal(9,2) DEFAULT NULL,
PRIMARY KEY (`username`,`GoalDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;It looks to me like when I call the stored procedure, it's ignoring my WHERE clause. I've been staring at this for a crazy long time and don't see anything wrong. What am I missing?
Thanks!
Solution
Right From the MySQL 8.0 Docs
It is possible for UPDATE and DELETE statements to produce an error in safe-updates mode even with a key specified in the WHERE clause, if the optimizer decides not to use the index on the key column:
-
Range access on the index cannot be used if memory usage exceeds that permitted by the range_optimizer_max_mem_size system variable. The optimizer then falls back to a table scan. See Limiting Memory Use for Range Optimization.
-
If key comparisons require type conversion, the index may not be used (see Section 8.3.1, “How MySQL Uses Indexes”). Suppose that an indexed string column c1 is compared to a numeric value using WHERE c1 = 2222. For such comparisons, the string value is converted to a number and the operands are compared numerically (see Section 12.3, “Type Conversion in Expression Evaluation”), preventing use of the index. If safe-updates mode is enabled, an error occurs.
As of MySQL 8.0.13, safe-updates mode also includes these behaviors:
-
EXPLAIN with UPDATE and DELETE statements does not produce safe-updates errors. This enables use of EXPLAIN plus SHOW WARNINGS to see why an index is not used, which can be helpful in cases such as when a range_optimizer_max_mem_size violation or type conversion occurs and the optimizer does not use an index even though a key column was specified in the WHERE clause.
-
When a safe-updates error occurs, the error message includes the first diagnostic that was produced, to provide information about the reason for failure. For example, the message may indicate that the range_optimizer_max_mem_size value was exceeded or type conversion occurred, either of which can preclude use of an index.
-
For multiple-table deletes and updates, an error is produced with safe updates enabled only if any target table uses a table scan.
Based on the these things, you need to run this
If your output shows
If your output shows
The fact that you can execute it by hand shows that the client program you are using to connect allows you to run the query. You may need to review the setting in MySQL Workbench to see if
It is possible for UPDATE and DELETE statements to produce an error in safe-updates mode even with a key specified in the WHERE clause, if the optimizer decides not to use the index on the key column:
-
Range access on the index cannot be used if memory usage exceeds that permitted by the range_optimizer_max_mem_size system variable. The optimizer then falls back to a table scan. See Limiting Memory Use for Range Optimization.
-
If key comparisons require type conversion, the index may not be used (see Section 8.3.1, “How MySQL Uses Indexes”). Suppose that an indexed string column c1 is compared to a numeric value using WHERE c1 = 2222. For such comparisons, the string value is converted to a number and the operands are compared numerically (see Section 12.3, “Type Conversion in Expression Evaluation”), preventing use of the index. If safe-updates mode is enabled, an error occurs.
As of MySQL 8.0.13, safe-updates mode also includes these behaviors:
-
EXPLAIN with UPDATE and DELETE statements does not produce safe-updates errors. This enables use of EXPLAIN plus SHOW WARNINGS to see why an index is not used, which can be helpful in cases such as when a range_optimizer_max_mem_size violation or type conversion occurs and the optimizer does not use an index even though a key column was specified in the WHERE clause.
-
When a safe-updates error occurs, the error message includes the first diagnostic that was produced, to provide information about the reason for failure. For example, the message may indicate that the range_optimizer_max_mem_size value was exceeded or type conversion occurred, either of which can preclude use of an index.
-
For multiple-table deletes and updates, an error is produced with safe updates enabled only if any target table uses a table scan.
Based on the these things, you need to run this
select @@global.sql_safe_updates,@@session.sql_safe_updates;If your output shows
1 for @@global.sql_safe_updates,- mysqld process was started up with
sql_safe_updatesori-am-a-dummy.
- Otherwise, it was not started that way.
If your output shows
0 for @@session.sql_safe_updates, that means your client is setting it- The client will automatically have
@@session.sql_safe_updatesset to whatever is in@@global.sql_safe_updates
- If the client has
@@session.sql_safe_updatesset to something different from@@global.sql_safe_updates, then the client is personally setting it.
The fact that you can execute it by hand shows that the client program you are using to connect allows you to run the query. You may need to review the setting in MySQL Workbench to see if
--safe-updates is being imposed on stored procedure. Other than these things, please check out suggestions from StackOverflow on how to tweek safe-updates off and on in the Workbench.Code Snippets
select @@global.sql_safe_updates,@@session.sql_safe_updates;Context
StackExchange Database Administrators Q#278143, answer score: 2
Revisions (0)
No revisions yet.