web-dev-qa-db-fra.com

Comment utiliser une instruction if après un CTE (SQL Server 2005)

La nuit dernière, j’écrivais un simple programme T-SQL, quelque chose comme ceci

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

J'ai trouvé après compilation qu'il y avait une erreur comme "une instruction incorrecte près de si"

Qu'est-ce qui ne va pas?

Cependant, je l'ai fait en utilisant un autre moyen. Mais je voulais savoir pourquoi cela ne fonctionnait pas!

21
priyanka.sarkar

Les expressions de table communes sont définies dans le contexte d'une seule instruction:

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

Donc, vous pouvez faire quelque chose comme:

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

ou

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

Un CTE doit être suivi d'une seule instruction SELECT, INSERT, UPDATE, MERGE ou DELETE faisant référence à certaines ou à toutes les colonnes CTE. Un CTE peut également être spécifié dans une instruction CREATE VIEW dans le cadre de l'instruction SELECT définissante de la vue.

23
Remus Rusanu

Le plus proche que vous obtiendrez utilisera UNION ALL pour faire une sélection brute commutée:

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
8
gbn

Un peu tard mais je ne peux pas être le seul à me cogner dessus.

Une solution pourrait être de créer une table temporaire comme celle-ci:

-- 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
5
DerpyNerd

Essayez de mettre le CTE dans la SI. Cela a fonctionné pour moi.

SI @awsome = 1 COMMENCE; AVEC CTE COMME (SÉLECTIONNEZ * À PARTIR DE SOMETABLE) CHOISISSEZ 'CE QUE VOUS VOULEZ' À PARTIR DE LA FIN DE CTE SI @awesome = 2 COMMENCE; CTE2 COMME (SÉLECTIONNEZ * À PARTIR DE SOMETABLE)

0
CW1255