简体   繁体   English

MySQL事务和变量的问题

[英]Issues with MySQL transactions and variables

I'm trying to set up a process where my team can do some routine DB changes using variables and a basic script. 我正在尝试建立一个流程,使我的团队可以使用变量和基本脚本对数据库进行一些常规更改。 I'm only on the first of many operations and can't even get it to execute. 我只是许多操作中的第一个,甚至无法执行它。 The idea is you assign the variables at the top of the script and say if you want to run the script in test or prod mode. 想法是在脚本顶部分配变量,并说出是否要在testprod模式下运行脚本。

test should just mock the changes, show you what would've happened and roll the transaction back while prod will actually commit the transaction and show you the updated rows. test应该只是模拟所做的更改,向您显示将会发生的情况,然后回滚事务,而prod实际上会提交事务并向您显示更新的行。

When I run these lines individually they work, but altogether it keeps saying syntax error. 当我分别运行这些行时,它们可以工作,但是总的来说,它一直在说语法错误。 I would love help debugging this but also if anyone has a better solution to this problem I'm wide open to hearing it. 我很乐意帮助调试此问题,但是如果有人对这个问题有更好的解决方案,我也乐于助人。

Ok here's the starting code, thanks in advance! 好的,这是开始代码,在此先感谢!

#ADD A NEW QUESTION CATEGORY
SET @new_category_name = 'NEW CATEGORY NAME HERE';
SET @prod_or_test = 'PROD';

START TRANSACTION;
#SET IT'S SORT_ORDER TO BE AT THE END OF THE LIST
SET @last_sort_order = ((SELECT MAX(`sort_order`) FROM question_categories)+1);

#INSERT THE NEW ROW
INSERT INTO question_categories (name, sort_order) VALUES (@new_category_name, @last_sort_order);
IF (@prod_or_test = 'PROD') THEN
  COMMIT;
  SELECT * FROM question_categories WHERE name = @new_category_name;
ELSE
  ROLLBACK;
END IF;

Updated to include the error messages: 更新以包含错误消息:

[ERROR in query 6] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF (@prod_or_test = 'PROD') THEN
  COMMIT' at line 1
[ERROR in query 8] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ELSE
  ROLLBACK' at line 1
[ERROR in query 9] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END IF' at line 1

IF , THEN , ELSE and END IF are not valid SQL statements, outside of the context of a MySQL stored program . 在MySQL 存储程序上下文之外, IFTHENELSEEND IF是无效的SQL语句。 For example a PROCEDURE or a TRIGGER definition. 例如,PROCEDURE或TRIGGER定义。

Reference: https://dev.mysql.com/doc/refman/5.7/en/if.html 参考: https : //dev.mysql.com/doc/refman/5.7/en/if.html

The IF statement can be used in stored programs, but it can't be used as a standalone SQL statement. IF语句可以在存储程序中使用,但不能用作独立的SQL语句。

Also, the IF statement shouldn't be confused with the IF() function, which can be used in the context of a statement such as a SELECT or UPDATE , which are valid SQL statements. 同样, IF语句不应与IF()函数混淆,该函数可以在诸如SELECTUPDATE类的有效SQL语句的上下文中使用。

  SELECT t.foo, IF(t.foo='bar',41,NULL) AS bar, ...   

Some statements include the IF keyword as part of their syntax, for example: 一些语句将IF关键字作为其语法的一部分,例如:

  DROP TABLE IF EXISTS foo; 

Note that in this example, the IF keyword is part of a DROP statement; 请注意,在此示例中, IF关键字是DROP语句的一部分; it's not a separate statement. 这不是单独的声明。


FOLLOWUP 跟进

" the end goal was to have one script ... but ... it's looking like I actually am trying to have some stored procedures that can be called via this script. " 最终目标是拥有一个脚本……但是……看来我实际上正在尝试拥有一些可以通过该脚本调用的存储过程。

The original answer (above) was addressing the usage of the IF statement outside of a MySQL stored program. 上面的原始答案是要解决MySQL存储程序之外的IF语句的用法。 If you need to use the IF statement, then that could be done in a PROCEDURE. 如果需要使用IF语句,则可以在PROCEDURE中完成。

However, an IF statement isn't strictly required. 但是,并非严格要求IF语句。 You could accomplish nearly the same thing using PREPARE , EXECUTE and DEALLOCATE PREPARE statements to execute dynamically created SQL. 您可以使用PREPAREEXECUTEDEALLOCATE PREPARE语句执行动态创建的SQL,几乎可以完成相同的事情。

Reference: https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html 参考: https : //dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html

For example, we could perform a conditional test on a user defined variable in an IF() function in a SELECT statement, and conditionally return a SQL text to execute. 例如,我们可以在SELECT语句的IF()函数中对用户定义的变量执行条件测试,然后有条件地返回要执行的SQL文本。 In this case, either a COMMIT or a ROLLBACK statement. 在这种情况下,可以使用COMMITROLLBACK语句。

I think something like this would work: 我认为这样会起作用:

 -- add a new question category
 SET @new_category_name := 'NEW CATEGORY NAME HERE';
 SET @prod_or_test := 'PROD';

 START TRANSACTION;

 -- set it's sort_order to be at the end of the list
 SELECT IFNULL(MAX(`sort_order`)+1,1) 
   FROM question_categories
   INTO @last_sort_order 
 ;

 -- insert the new row
 INSERT INTO question_categories (name, sort_order)
 VALUES (@new_category_name, @last_sort_order)
 ;

 -- conditionally execute a COMMIT or ROLLBACK
 SELECT IF(@prod_or_test='PROD','COMMIT','ROLLBACK') INTO @sql;
 PREPARE stmt FROM @sql;
 EXECUTE stmt;
 DEALLOCATE PREPARE stmt;

 SELECT *
   FROM question_categories
  WHERE @prod_or_test = 'PROD'
    AND name = @new_category_name ;

issue is with the brackets 问题在于括号

IF (@prod_or_test = 'PROD') THEN

to

IF @prod_or_test = 'PROD' THEN

syntax 句法

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

https://dev.mysql.com/doc/refman/5.7/en/if.html https://dev.mysql.com/doc/refman/5.7/zh-CN/if.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM