昨夜私はこのような単純な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の近くの不正なステートメント」のようなエラーがスローされていることがわかりました
なにが問題ですか?
しかし、私は他の方法でそれを行いました。しかし、それがうまくいかない理由を知りたかったのです。
共通テーブル式 は、単一のステートメントのコンテキスト内で定義されます。
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の後には、一部またはすべてのCTE列を参照する単一のSELECT、INSERT、UPDATE、MERGE、またはDELETEステートメントが続く必要があります。 CTEは、ビューのSELECTステートメントの定義の一部として、CREATE VIEWステートメントでも指定できます。
あなたが得る最も近いものは、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
少し遅れますが、これにぶつかるのは私だけではありません。
解決策は、次のような一時テーブルを作成することです。
-- 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
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