将 IF EXISTS 与 CTE 一起使用

Posted

技术标签:

【中文标题】将 IF EXISTS 与 CTE 一起使用【英文标题】:Using IF EXISTS with a CTE 【发布时间】:2016-09-19 15:26:17 【问题描述】:

我想检查 CTE 表是否有记录或为空。但是对于下面的 SQL,我总是收到错误消息“关键字 'IF' 附近的语法不正确”。现在 ADMISSION_OUTSIDE TABLE 中没有匹配的记录。 SQl 的结果应该打印“NOT OK”。谢谢,

WITH ADMISSION_OUTSIDE AS 
(   .....
.....
)

IF EXISTS (SELECT * FROM ADMISSION_OUTSIDE)
PRINT 'OK'
ELSE PRINT 'NOT OK'

【问题讨论】:

一个 cte 后面应该跟 SELECT, INSERT, UPDATE, or DELETE 语句 也许你在这里做的有点混乱。这不是正确的语法,也可能不是 CTE 的正确用法。也许您只想将查询的内容放在您的 CTE 中的表变量中。请注意,在 CTE 定义之后的命令之后,您没有范围内的 CTE 您只是打印以调试查询吗?或者您是否还打算从中选择数据? CTE 相对于子查询的好处主要在于它的结果集可以在 SELECT/INSERT/UPDATE/DELETE 语句中重复使用。就像 f.e.在 Prdp 的回答中。但也许你应该看看cursor 可以实现什么。 【参考方案1】:

来自MSDN

CTE 后面必须跟一个 SELECT、INSERT、UPDATE 或 DELETE 引用部分或全部 CTE 列的语句

可以这样改写

WITH ADMISSION_OUTSIDE AS 
(   .....
.....
)
SELECT 'OK' WHERE EXISTS (SELECT * FROM ADMISSION_OUTSIDE)
UNION ALL
SELECT 'NOT OK' WHERE NOT EXISTS (SELECT * FROM ADMISSION_OUTSIDE)

这是一个演示

;WITH CTE AS
(
SELECT 1 as a WHERE 1=0
)
SELECT 'OK' WHERE EXISTS (SELECT * FROM CTE)
UNION ALL
SELECT 'NOT OK' WHERE NOT EXISTS (SELECT * FROM CTE)

结果: NOT OK

;WITH CTE AS
(
SELECT 1 as a WHERE 1=1
)
SELECT 'OK' WHERE EXISTS (SELECT * FROM CTE)
UNION ALL
SELECT 'NOT OK' WHERE NOT EXISTS (SELECT * FROM CTE)

结果: OK

【讨论】:

我得到了空白值。 @Ice - 还添加了演示 如果您不喜欢 UNION,您可以使用 case 语句,例如SELECT case when exists (SELECT * FROM CTE) then 'OK' else 'NOT OK' end 【参考方案2】:

我认为这也是检查值存在并执行操作的一种最简单的方法。

WITH ADMISSION_OUTSIDE AS 
(   .....
.....
)
SELECT CASE WHEN (SELECT COUNT(1) tot 
                  FROM ADMISSION_OUTSIDE) > 0 THEN 'OK' ELSE 'NOT OK' END

【讨论】:

EXISTS 将在找到匹配项时停止读取数据。 COUNT 将读取与谓词对应的所有行。一般来说,EXISTS 更有效。 你认为check if a CTE table has record or null不适合回答吗?【参考方案3】:

有点老套,但你可以这样做:

declare @x bit

;WITH CTE AS
(
  SELECT 1 As 'column1'
)
SELECT @x = ISNULL(column1,0) from cte

If @x=1
begin
...
end

【讨论】:

【参考方案4】:

因为必须使用 with 语句结果后跟 with 语句。不允许除结果外的任何其他语句。

更多信息请参考:Unable to Drop a table after a WITH statement

【讨论】:

【参考方案5】:

SQL Server 返回该错误消息(“语法错误”),因为它不是有效的语句。

公用表表达式 (CTE) 本身并不是一个单独的语句。它是一个表达式,它是另一个语句的一部分,可以是 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句。

https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

【讨论】:

以上是关于将 IF EXISTS 与 CTE 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

将多个 CTE 与多个临时表一起使用

嘲弄:如何将 shouldReceive 与 method_exists 一起使用?

与 CTE 一起与 CREATE/INSERT 一起使用

如何将 synchronize.js 与节点的 fs.exists 一起使用?

Postgres - 使用 CTE 的 id 列的唯一值,与 GROUP BY 一起加入

你如何与多个 CTE 联合?