【发布时间】:2016-10-06 12:53:17
【问题描述】:
我正在尝试设置一些 SQL 测试查询,以在 SQL 表中记录测试是通过还是失败。这些测试查询在几个单独的数据库上运行。下面是一个使用基本查询的示例(在 IF 语句内):
DECLARE @dbname NVARCHAR(200);
DECLARE @query NVARCHAR(MAX);
DECLARE db_cursor CURSOR FOR
SELECT name FROM sys.databases
WHERE name LIKE '%JMPTIPR%'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
SET @query = CAST('
DECLARE @testStatus NVARCHAR(MAX);
DECLARE @name NVARCHAR(MAX);
DECLARE @version NCHAR(10);
DECLARE @testid INT;
DECLARE @repid INT;
SELECT @name = Column1 from [' +@dbname+ '].dbo.Table1
where Column1 = ''File Name''
SELECT @version = attributedata from [' +@dbname+ '].dbo.Table1
where Column1 = ''Version Number''
SELECT @testid = COALESCE(MAX(TestNum), 0) FROM [Database1].dbo.Table2;
SELECT @repid = RepNum FROM [Database1].dbo.Table2
WHERE Date = (SELECT MAX(Date) FROM [Database1].dbo.Table2)
IF (
SELECT COUNT(*)
FROM [' +@dbname+ '].dbo.Table1
WHERE [' +@dbname+ '].dbo.Table1.Column1 LIKE ''%execution%''
) IS NOT NULL
SET @testStatus = ''Test Passed''
ELSE
SET @testStatus = ''Test Failed''
INSERT INTO [Database1].dbo.Table3 (FileName, Version, Result, Date, TestNum, RepNum)
VALUES (@name, @version, @testStatus, GETDATE(), @testid, @repid)'
AS NVARCHAR(MAX))
EXECUTE (@query)
FETCH NEXT FROM db_cursor INTO @dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor;
问题是我有几个更复杂的查询,我想做同样的事情。如果一切都按计划进行,我有一个预期的结果应该返回,如果出现问题,我有一个预期的结果。因此,这是我想要包含的更复杂查询之一的示例: (值得注意的是,我不希望任何人通过“修复”查询来简单地回答这个问题。我有太多东西要放在这里让别人修复,我宁愿自己学习如何去做。)
SELECT Table1.Column1, Table2.Column2, Table3.Column3,
Table3.Column4, Table3.Column5, Table3.Column6,
Table3.Column7
FROM Table2 INNER JOIN
Table3 ON Table3.Column8 = Table2.id INNER JOIN
Table1 ON Table2.Column9 = Table1.id
WHERE (Table3.Column5 = -1 AND Table3.Column7 > 0) OR
(Table3.Column5 = -1 AND Table3.Column6 > 0) OR
(Table3.Column5 > Table3.Column6 AND Table3.Column6 > 0) OR
(Table3.Column6 > Table3.Column7 AND Table3.Column7 > 0)
当我将此查询添加到我的 if 语句中(并将 if 条件更改为 IS NOT NULL)时,我收到错误消息:
Msg 116, Level 16, State 1, Line 24
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 116, Level 16, State 1, Line 24
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
对我来说,最终的问题似乎是我对 SQL 的理解不够深入,无法完成这些工作。
编辑:我看到几个 cmets 说因为我没有显示不起作用的代码,所以您无法修复它。我假设您的意思是我提供的示例代码不够具体。
但是,这没有抓住我的问题的重点。我不希望你修复那个特定的代码。我的问题是关于原始 If/Else 代码无法处理某些更复杂的 SQL 查询(比如带回完整表的查询)。
也许为我提供的示例代码提供更多上下文,它是一个查询,它要么不返回任何内容(“测试通过”条件),要么返回一个包含多行和多列的表( “测试失败”条件)。我在询问如何获取适用于简单查询的原始查询并将其调整为无法简单“计数”或其他简单功能的查询。
【问题讨论】:
-
就像错误所说的那样,在只允许一个字段的上下文中,您有一个返回多个字段的子查询。例如
select ... where foo = (select field1, field2 from ....)。foo应该与什么值进行比较?field1?或field2?因此错误 - 您需要消除歧义 -
我理解您的观点,但如果您不向我们提供 SQL 语句的代码,我们将无法修复 SQL 语句。很高兴您给了我们错误代码...但是请给我们实际的错误 SQL。
-
另外,您可能只需要了解
EXISTS()的工作原理 -
警告:不要这样做:
'[' + @dbname + ']',这样做:+ QUOTENAME(DB_NAME(DB_ID(@dbname))) +为什么? (1)QUOTENAME()使用[和]字符正确转义垃圾,并且 (2) 包装DB_NAME()/DB_ID()确保传递的数据库名称实际上是有效的。 -
@Paparazzi 所以?试试
CREATE DATABASE "foo]bar";- 如果没有QUOTENAME(),它仍然会中断。而且,如果有人从该代码中学习或将其复制到其他地方,通常可以认为使用'[' + @dbname + ']'是可以的,包括提供@dbname作为用户输入的情况,并且存在不那么明显的危险与此相关。
标签: sql-server if-statement exists