仅当条件满足时运行SQL查询

5
我正在尝试编写一个“傻瓜式”的SQL脚本,可以由非SQL专业人员运行。
我的想法是在脚本顶部定义几个变量,然后根据这些变量运行特定的查询。
我在mySQL上进行测试,但最终将在SQL-Server上运行。
以下是我正在尝试做的伪代码:
# Set matchThis to the value to match
SET @matchThis = "matchMe";

# Uncomment (remove the #) one of the two lines below to update or just view
#SET @update = "YES";
SET @update = "NO";

IF @update = "YES" {
    UPDATE myTable SET myColumn = "changed" WHERE matchVal = @matchThis;
} ELSE {
    SELECT * FROM myTable WHERE matchVal = @matchThis;
}

如果有办法,我希望您能完全使用SQL来完成此操作。

我看过有关使用 SELECT IF 等的指南,但无法弄清如何实现上述操作。


7
你想授权一位不熟悉SQL语言的用户访问你的服务器以执行SQL脚本?这听起来至少是非常危险的。 - WeSt
2
将任何你想要的 SQL 放入一个存储过程中并运行它。 - Mihai
1
使用一个产品来测试针对另一个产品的SQL并不是最好的想法。即使在这样简单的情况下,也会出现差异,这些差异会让您感到困扰。参数处理不同,Unicode支持不同,像IF这样的过程语句也不同。 SELECT IF相当于SQL Server中的CASE,而不用于条件执行。 - Panagiotis Kanavos
1
正如 @Mihai 建议的那样,最安全的方法是将所有内容放在存储过程中,并限制用户指定参数。在这种情况下,您可以完全控制脚本。 - WeSt
1
错误处理是不同的。一个易于使用的脚本应该能够处理异常,这是完全不同的。事务处理也是不同的,这可能会导致您的脚本在每台机器上表现不同。 - Panagiotis Kanavos
显示剩余7条评论
3个回答

3

这是针对MSSQL的。我认为你已经掌握了所有内容,但语法可能还需要调整。希望这可以帮到你。

DECLARE @matchthis AS VARCHAR(MAX)
DECLARE @update AS VARCHAR(1)

SET @matchthis = 'matchme'
--@update can be Y or N. User changes this here.
SET @update = 'Y'

IF @update = 'Y'
    UPDATE mytable SET myColumn = 'changed' WHERE matchval = @matchthis
ELSE IF @update = 'N'
    SELECT * FROM myTable WHERE matchval = @matchthis

我不知道是否要将更改设为变量,但如果您想将其设置为变量,请按照与 @matchthis 相同的语法(声明和设置)进行操作。

如果您想使此更加易于理解,我建议最好的方法是创建一个存储过程,这样用户就不会看到代码,只有输入框。


1
这里有两个问题。一个是为什么IF语句不起作用——因为T-SQL没有花括号。语法在文档中说明。
然而,更重要的问题是如何在不修改脚本本身的情况下向脚本传递参数。这可以使用脚本变量来完成。当使用sqlcmd命令执行脚本时,任何形式为$(SomeName)的文本都会被替换为具有相同名称的命令行参数或环境变量。
例如,如果您有以下脚本:
USE AdventureWorks2012;
SELECT x.$(ColumnName)
FROM Person.Person x
WHERE c.BusinessEntityID < 5;

这个命令将以FirstName作为列名运行。
sqlcmd -v ColumnName ="FirstName" -i c:\testscript.sql

1
我意识到我原始帖子中的IF语法是完全不正确的。这就是为什么我称它为伪代码的原因。但我希望Gordon Linoff现在已经让我走上了正确的轨道... - Fat Monk

1

如果您希望获得在MySQL和SQL Server中都能运行的脚本,那么您是非常乐观的。然而,对于您的基本脚本,您可以这样做:

-- Set matchThis to the value to match
SET @matchThis = 'matchMe';

-- Uncomment (remove the #) one of the two lines below to update or just view
-- SET @update = 'YES';
SET @update = 'NO';

UPDATE myTable
    SET myColumn = 'changed'
    WHERE matchVal = @matchThis AND @update = 'YES';

SELECT *
FROM myTable
WHERE matchVal = @matchThis AND @update <> 'YES';

这与您的脚本略有不同。如果@update'YES',则它会实际运行select,但不会返回任何行。
两个注意点:
  • SQL Server不使用双引号表示字符串常量。
  • MySQL不允许使用if语句,除非在存储程序中。
  • 注释一行的标准机制是两个连字符(--
如果需要在T-SQL中运行脚本,应使用T-SQL开发。

1
到目前为止,这是最接近我想要实现的。但是当我将“AND @update…”添加到where子句时,没有返回任何行... - Fat Monk
1
@FatMonk update 的值是多少?如果它是 null,那么检查将失败,因为与 null 的任何比较都会失败。还要注意,这种语法只适用于脚本。SQL Server 会缓存命令/存储过程的执行计划,在第一次使用时。如果后续调用导致行为发生根本性变化,则缓存的执行计划可能不适用,并且会导致低效的查询。 - Panagiotis Kanavos
1
@FatMonk . . . 真遗憾,我错过了。你也不能使用变量。SQL Server需要declare。MySQL只允许在程序块中使用declare。放弃这个想法吧。在SQL Server上进行开发。 - Gordon Linoff
1
奇怪的是使用 ...AND @update LIKE 'YES';...AND @update NOT LIKE 'YES'; 似乎可以工作。 - Fat Monk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接