web-dev-qa-db-fra.com

exec a échoué parce que le nom n'est pas un identifiant valide?

J'ai une requête dont j'ai besoin de l'exécuter en tant que requête dynamique pour générer un nom de colonne significatif. Par exemple, si j'exécute directement la requête, les données sont renvoyées correctement. Cependant, si j'utilise le code ci-dessous, il indique:

The name '
            SELECT (CASE WHEN A.Domain IS NOT NULL THEN A.Domain ELSE B.Domain END) AS [Domain], 
                    (CASE WHEN A.Email IS NOT NULL THEN A.Email ELSE B.Email END) AS [Email], 
                    A.[Sender Size] AS [Sender Size 1], A.[Sender Count] AS [Sender Count 1],
                        A.[Receiver Size] AS [Receiver Size 1], A.[Receiver Count] AS [Receiver Count 1],
                    A.[Sender Size 2] AS [Sender Size 2], A.[Sender Count 2] AS [Sender Count 2],
                        A.[Receiver Size 2] AS [Receiver Size 2], A.[Receiver Count 2] AS [Receiver Count 2],
                    B.SenderSize AS [Sender Size Average], B.SenderCount AS [Sender Count Average],
                        B.ReceiverSize AS [Receiv' is not a valid identifier.

Ci-dessous, le code:

DECLARE @query NVARCHAR(4000)
SET @query = N'SELECT *
            FROM
            (
                SELECT (CASE WHEN A.Domain IS NOT NULL THEN A.Domain ELSE B.Domain END) AS [Domain], 
                        (CASE WHEN A.Email IS NOT NULL THEN A.Email ELSE B.Email END) AS [Email], 
                        A.[Sender Size] AS [Sender Size 1], A.[Sender Count] AS [Sender Count 1],
                            A.[Receiver Size] AS [Receiver Size 1], A.[Receiver Count] AS [Receiver Count 1],
                        A.[Sender Size 2] AS [Sender Size 2], A.[Sender Count 2] AS [Sender Count 2],
                            A.[Receiver Size 2] AS [Receiver Size 2], A.[Receiver Count 2] AS [Receiver Count 2],
                        B.SenderSize AS [Sender Size Average], B.SenderCount AS [Sender Count Average],
                            B.ReceiverSize AS [Receiver Size Average], B.ReceiverCount AS [Receiver Count Average]
                FROM
                    (
                    SELECT (CASE WHEN tf.Domain IS NOT NULL THEN tf.Domain ELSE tf2.Domain END) AS Domain, 
                            (CASE WHEN tf.Email IS NOT NULL THEN tf.Email ELSE tf2.Email END) AS Email, 
                         ISNULL(tf.SenderSize,0) AS [Sender Size] , ISNULL(tf.SenderCount,0) AS [Sender Count], ISNULL(tf.ReceiverSize,0) AS [Receiver Size], ISNULL(tf.ReceiverCount,0) AS [Receiver Count], 
                         ISNULL(tf2.SenderSize,0) AS [Sender Size 2], ISNULL(tf2.SenderCount,0) AS [Sender Count 2], ISNULL(tf2.ReceiverSize,0) AS [Receiver Size 2], ISNULL(tf2.ReceiverCount,0) AS [Receiver Count 2] 
                    FROM #TrafficFinal tf FULL JOIN #TrafficFinal2 tf2 ON (tf.Email = tf2.Email AND tf.Domain = tf2.Domain)
                    ) A FULL JOIN #TrafficFinal3 B ON (A.Email = B.Email AND A.Domain = B.Domain)
            ) C
            ORDER BY Domain, Email';    

PRINT @query;

-- run it
exec @query;

Est-ce à cause de la jointure complète? 

51
urlreader

Essayez plutôt ceci à la fin:

exec (@query)

Si vous ne disposez pas des crochets, SQL Server considère que la valeur de la variable est un nom de procédure stockée.

OR

EXECUTE sp_executesql @query

Et cela ne devrait pas être à cause de FULL JOIN.
Mais j'espère que vous avez déjà créé les tables temporaires: #TrafficFinal, # TrafficFinal2, # TrafficFinal3 avant cela.


Veuillez noter qu'il existe des considérations de performance entre l'utilisation de EXEC et de sp_executesql. Parce que sp_executesql utilise la mise en cache d’instruction forcée comme un sp.
Plus de détails ici


Sur une autre note, y a-t-il une raison pour laquelle vous utilisez SQL dynamique dans ce cas, lorsque vous pouvez utiliser la requête telle quelle, sachant que vous ne faites aucune manipulation de requête et ne l'exécutez pas telle qu'elle est?

188
Kash

Comme dans mon cas, si votre SQL est généré par concaténation ou utilise des convertis, SQL à exécuter doit être précédé de la lettre N comme ci-dessous

par exemple. 

Exec N'Select bla..' 

le N définit la chaîne littérale est unicode.

0
Moji