我有一个SQL脚本需要运行在一个大型数据库上,我想在开始时加入几个简单的查询作为安全检查。
是否有办法在MySQL中编写断言?或者任何一种“选择...,如果它不匹配这个值,那么终止整个脚本”的方式?
一些疯狂的代码。重点是:在 mysql 变量中,SET
命令可能会引发错误。
例如:
SET @value = 0;
SET SESSION sql_mode = if(@value, @@SESSION.sql_mode, 'something wrong uphere');
执行结果将会输出ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'something wrong uphere'
,并且程序会停止执行。
这种方法虽然不够语义化,但是可以实现功能。
你可以将整个脚本放在if语句中,取决于你需要检查的值类型,以下是一个例子:
DECLARE @value int
SET @value = (SELECT COUNT(*) FROM dbo)
IF @value >0
BEGIN
--Do Stuff Here
END
你也可以通过存储过程/函数来实现这一点,就像下面的示例一样:
CREATE FUNCTION `RunProcess`() RETURNS INT(11)
runProcess:BEGIN
DECLARE check_value INT;
DECLARE error_code INT;
SELECT COUNT(*) FROM dbo INTO check_value;
IF check_value = 0 THEN set error_code = 666;
LEAVE runProcess;
RETURN error_code;
END IF;
...
...
END;
解决这个问题的一种方法是,如果断言失败,则故意使插入操作失败。这并不美观,但很简单且有效。
假设Table1包含columnA和columnB。您想要插入值('any', 'thing')
到该表中,但仅当这些值满足某些条件时才能插入。
然后可以像这样操作:
SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( your conditions...);
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);
“any” 和 “thing” 值显然会在查询运行时插入。如果您的 Table1 设置为仅接受列 A 或 B 中的非空值,则当条件失败时,这将失败。
一个非常简单的荒谬示例(显然可以通过其他方式实现,这只是一个例子 :-),如果您希望值不同:
SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( 'a'!='b');
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);
测试条件不必基于您要插入的值:
SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( 'another' IS NOT NULL);
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);
如果您的目标不是执行插入操作,则可以将相同的逻辑应用于不同的事务类型,其思想是更改变量以使查询失败。
或者,您可以为此目的创建一个虚拟表,其中包含一个非空列,并始终将断言结果插入虚拟表的第一行。这不太美观,但它有效 :-)