it-swarm.com.de

exec schlug fehl, weil der Name kein gültiger Bezeichner ist?

Ich habe eine Abfrage, die ich als dynamische Abfrage ausführen muss, um einen aussagekräftigen Spaltennamen auszugeben. Wenn ich beispielsweise die Abfrage direkt starte, werden die Daten korrekt zurückgegeben. Wenn ich jedoch folgenden Code verwende, wird Folgendes angezeigt:

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.

Darunter ist der 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;

Liegt es am vollen Join? 

51
urlreader

Versuchen Sie es stattdessen am Ende:

exec (@query)

Wenn Sie keine Klammern haben, nimmt SQL Server an, dass der Wert der Variablen der Name einer gespeicherten Prozedur ist.

OR

EXECUTE sp_executesql @query

Und es sollte nicht wegen FULL JOIN sein.
Aber ich hoffe, Sie haben bereits die temporären Tabellen erstellt: #TrafficFinal, # TrafficFinal2, # TrafficFinal3.


Bitte beachten Sie, dass es zwischen der Verwendung von EXEC und sp_executesql Überlegungen zur Leistung gibt. Weil sp_executesql ein Zwischenspeichern von Anweisungen wie ein sp verwendet.
Weitere Details hier


Gibt es noch einen Grund, warum Sie dynamische SQL für diesen Fall verwenden, wenn Sie die Abfrage so verwenden können, dass sie keine Abfragemanipulationen durchführen und sie so ausführen, wie sie ist?

188
Kash

Wie in meinem Fall, wenn Ihre SQL durch Verketten erzeugt wird oder Konvertierungen verwendet, muss der SQL-Anweisung bei der Ausführung der Buchstabe N vorangestellt werden

z.B. 

Exec N'Select bla..' 

das N definiert das String-Literal als Unicode.

0
Moji