如何在 CTE 之后使用 if 语句 (SQL Server 2005)

问题描述 投票:0回答:5

昨晚我正在编写一个简单的 T-SQL 程序,如下所示

DECLARE @ROLEID AS INT

SELECT @ROLEID = [ROLE ID] FROM TBLROLE

;WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)
IF (@ROLEID  = 1) 
BEGIN
      //SOMECODE
END
ELSE IF(@ROLEID  = 2) 
BEGIN
      //SOMECODE
END
ELSE
BEGIN 
      //SOMECODE
END

我在编译后发现它抛出错误,例如“IF附近的语句不正确”

出了什么问题?

但是,我通过其他方式做到了这一点。但我想知道为什么它不起作用!

sql sql-server sql-server-2005 t-sql common-table-expression
5个回答
28
投票

公用表表达式在单个语句的上下文中定义:

WITH cte_name AS (
  <cte definition>)
<statement that uses cte>;

所以你可以这样做:

WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)
SELECT * FROM CTE;

WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)
UPDATE CTE 
SET somefield = somevalue
WHERE id = somekey;

CTE 后面必须跟着一个 选择、插入、更新、合并或 引用某些内容的 DELETE 语句 或所有 CTE 列。 CTE 还可以 在 CREATE VIEW 中指定 声明作为定义的一部分 视图的 SELECT 语句


14
投票

有点晚了,但我不是唯一遇到这个问题的人。

解决方案可能是创建一个像这样的临时表:

-- If previous run of this query fails, the temp table will be deleted.
-- Selecting into creates the temp table which fails if it already exists
IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#dtBalansOpgesteldGefilterd%') BEGIN
   DROP TABLE #temp
END;

;WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)

-- Followed by select statement as required
SELECT *
INTO #temp
FROM CTE

IF @awsome = 1
BEGIN
    SELECT 'WHATEVERYOUWANT' AS WhateverColumnNameYouWant, *
    FROM #temp
END

10
投票

您将得到的最接近的是使用 UNION ALL 进行粗略的切换选择:

DECLARE @ROLEID AS INT

SELECT @ROLEID = [ROLE ID] FROM TBLROLE

;WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)
SELECT
    --somecolumns
FROM
    CTE
    --other stuff too
WHERE
    @ROLEID = 1
UNION ALL
SELECT
    --somecolumns
FROM
    CTE
    --other stuff too
WHERE
    @ROLEID = 2
UNION ALL
SELECT
    --somecolumns
FROM
    CTE
    --other stuff too
WHERE
    @ROLEID = 3
...
UNION ALL
SELECT
    --somecolumns
FROM
    CTE
    --other stuff too
WHERE
    @ROLEID = n

2
投票

尝试将 CTE 放入 IF 中。这对我有用。

IF @awsome = 1
BEGIN
;WITH CTE
AS
( 
    SELECT * FROM SOMETABLE
)
    SELECT 'WHATEVERYOUWANT' FROM CTE
END
ELSE IF @awesome = 2
BEGIN
;WITH CTE2
AS
( 
    SELECT * FROM SOMETABLE
)
    SELECT 'WHATEVERYOUWANT' FROM CTE2
END

0
投票

在我的工作项目中,我对 SQL 存储过程有一个要求,其中我们通过登录用户 ID 过滤表中的记录。 现在,需要在报告页面中重复使用相同的存储过程,其中应显示该表的所有记录,而无需按登录用户进行过滤。 所以,这就是需要使用 IF .. ELSE 的地方。 在存储过程中,我们使用带有多个表、子查询和末尾 WHERE 子句的 JOIN => (WHERE userID = @loginUserID)

现在,对于上述要求,我所做的是 - 将登录用户 ID 作为可选参数,即,如果未提供,它将具有 NULL 值。

现在的挑战是 - 如何检查 如果 LoginUser 参数为 NULL / NOT NULL,并且 如果 NOT NULL,则在 WHERE 子句中使用它。

使用以下方法完成此操作=>

  1. 将逻辑包装在 CTE(公共表表达式)中
  2. 然后,从 CTE 表中执行 SELECT,并对其执行 WHERE - 如下所示: WHERE ((@loginUser IS NULL) OR (@loginUser IS NOT NULL AND cte.UserId = @loginUser))

并且,这对于两种情况都有效: 一个。其中LoginUser为NULL,将表中的所有记录获取到报告页面 b.其中LoginUser不为NULL,仅获取其他页面中通过LoginUser过滤的记录。

只是想分享。 希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.