MySQL 中的断言

发布于 2024-09-15 16:12:20 字数 111 浏览 3 评论 0原文

我有一个针对大型数据库运行的 SQL 脚本。我想在开始时提出几个简单的查询,作为健全性检查。

有没有办法在MySQL中写断言?或者任何类型的“选择...,如果它与该值不匹配,则中止整个脚本”?

I have a SQL script to run against a large database. I'd like to put a couple of simple queries at the start, just as a sanity check.

Is there any way to write an assertion in MySQL? Or any kind of "select ..., and if it doesn't match this value, then abort the entire script"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉墨 2024-09-22 16:12:20

一些疯狂的代码。要点是:SET 可能会引发 mysql 变量错误。

例如。

 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 bad uphere' 并且执行将停止。

这种方法不是语义性的,但它确实有效。

Some crazy code. Main point is: SET could raise error for mysql variables.

For example.

 SET @value = 0;
 SET SESSION sql_mode = if(@value, @@SESSION.sql_mode, 'something wrong uphere'); 

Would output ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'something wrong uphere' and execution would be stopped.

This approach is not semantic but it works.

半仙 2024-09-22 16:12:20

您可以将整个脚本放在 if 语句中,具体取决于您需要检查的值类型,下面是一个示例:

DECLARE @value int
SET @value = (SELECT COUNT(*) FROM dbo)

IF @value >0
BEGIN
 --Do Stuff Here
END

You could put the entire script in an if statement, depending on what kind of value you need to check, here's an example:

DECLARE @value int
SET @value = (SELECT COUNT(*) FROM dbo)

IF @value >0
BEGIN
 --Do Stuff Here
END
街角卖回忆 2024-09-22 16:12:20

您还可以通过存储过程/函数来执行此操作,如下例所示:

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;

You can also do this via a stored procedure / function, as in the example below:

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;
中二柚 2024-09-22 16:12:20

解决此问题的一种方法是,如果断言失败,则故意使插入失败。这并不漂亮,但是很简单并且有效。

假设 Table1 包含列 A 和列 B。您想要在此表中插入值 ('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);

如果您的目标不是执行插入,相同的逻辑可以应用于不同的事务类型,其想法是更改变量以使查询失败。

或者,您可以为此目的创建一个具有非空列的虚拟表,并始终将断言结果插入虚拟表的第一行。不漂亮,但它有效:-)

One way to go about this could be to make an insert fail on purpose if you assertion fails. This is not pretty, but it is simple and it works.

Let's say Table1 contains columnA and columnB. You want to insert into this table the values ('any', 'thing'), but ONLY if these values fulfil some conditions.

Then do something like this:

SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( your conditions...);
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);

the 'any' and 'thing' values would obviously be inserted at runtime in the query.
If you Table1 is set up to accept only non-null values in column A or B, this will fail when your conditions fail.

A very simple nonsensical example (this obviously can be achieved otherwise, this is only an example :-) ), if you want the values to differ:

SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( 'a'!='b');
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);

The test condition doesn't have to be on the values you are trying to insert:

SELECT 'any', 'thing' INTO @setA, @setB FROM DUAL WHERE ( 'another' IS NOT NULL);
INSERT INTO Table1 (columnA, columnB) VALUES (@setA, @setB);

If your goal is not to do perform an insert, the same logic can be applied on different transaction types, the idea being to alter the variables so they make the query fail.

Or you can create a dummy table just for this purpose, with a non-null column, and always insert your assertion result in the dummy table's first row. Not pretty, but it works :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文