Deklarieren Sie die Variable für eine Abfragezeichenfolge

91

Ich habe mich gefragt, ob es in MS SQL Server 2005 eine Möglichkeit gibt, dies zu tun:

  DECLARE @theDate varchar(60)
  SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

  SELECT    AdministratorCode, 
            SUM(Total) as theTotal, 
            SUM(WOD.Quantity) as theQty, 
            AVG(Total) as avgTotal, 
            (SELECT SUM(tblWOD.Amount)
                FROM tblWOD
                JOIN tblWO on tblWOD.OrderID = tblWO.ID
                WHERE tblWO.Approved = '1' 
                AND tblWO.AdministratorCode = tblWO.AdministratorCode
                AND tblWO.OrderDate BETWEEN @theDate
            )
 ... etc

Ist das möglich?

StealthRT
quelle

Antworten:

94

Es ist möglich, erfordert jedoch die Verwendung von dynamischem SQL.
Ich empfehle, den Fluch und den Segen von dynamischem SQL zu lesen, bevor Sie fortfahren ...

DECLARE @theDate varchar(60)
SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

DECLARE @SQL VARCHAR(MAX)  
SET @SQL = 'SELECT AdministratorCode, 
                   SUM(Total) as theTotal, 
                   SUM(WOD.Quantity) as theQty, 
                   AVG(Total) as avgTotal, 
                  (SELECT SUM(tblWOD.Amount)
                     FROM tblWOD
                     JOIN tblWO on tblWOD.OrderID = tblWO.ID
                    WHERE tblWO.Approved = ''1''
                      AND tblWO.AdministratorCode = tblWO.AdministratorCode
                      AND tblWO.OrderDate BETWEEN '+ @theDate +')'

EXEC(@SQL)

Dynamisches SQL ist nur eine SQL-Anweisung, die vor der Ausführung als Zeichenfolge zusammengesetzt wird. Es tritt also die übliche Verkettung von Zeichenfolgen auf. Dynamisches SQL ist immer dann erforderlich, wenn Sie etwas in der SQL-Syntax ausführen möchten, das nicht zulässig ist, z.

  • Ein einzelner Parameter zur Darstellung einer durch Kommas getrennten Liste von Werten für eine IN-Klausel
  • eine Variable, die sowohl den Wert als auch die SQL-Syntax darstellt (IE: das von Ihnen bereitgestellte Beispiel)

EXEC sp_executesql Ermöglicht die Verwendung von Bindungs- / PreparatedStatement-Parametern, sodass Sie sich bei SQL-Injection-Angriffen nicht darum kümmern müssen, einfache Anführungszeichen / etc zu vermeiden.

OMG Ponys
quelle
Ich denke, das ist die richtigste Antwort. Ich habe in letzter Zeit auch SQL Server 2005 verwendet, und die Verwendung einer Variablen zum Ersetzen von Abfragezeichenfolgen, wie sie das OP wünscht, ist nicht möglich (erzeugt Syntaxfehler). Variablen können nicht sowohl Syntax als auch Datentypen enthalten, wie @Ponies sagt. Dynamisches SQL ist der Weg, um Abfragen in SQL Server über Zeichenfolgen zu erstellen. Denken Sie daran, vorsichtig mit Ihren Zitaten und Typen umzugehen! Für die von Ihnen ausgeführte Zeichenfolge müssen einige Typen wie datetime oder int konvertiert oder für die Verkettung von Zeichenfolgen umgewandelt werden.
RoboBear
51
DECLARE @theDate DATETIME
SET @theDate = '2010-01-01'

Ändern Sie dann Ihre Abfrage, um diese Logik zu verwenden:

AND 
(
    tblWO.OrderDate > DATEADD(MILLISECOND, -1, @theDate) 
    AND tblWO.OrderDate < DATEADD(DAY, 1, @theDate)
)
Jäger
quelle
2
Abwarten. Das kann nicht die Antwort sein, wenn die Frage deutlich zwei verschiedene Daten zeigt. Wie haben Sie es am Ende @StealthRT codiert? Wo steht das Datum '2010-08-31' in der Antwort? In der Frage wird auch klar gefragt, ob Sie DECLARE-Variablen verwenden können, um Code durch eine andere SELECT-Anweisung zu ersetzen. Die richtige Antwort ist unten.
Fandango68
2

Verwenden von EXEC

Sie können das folgende Beispiel zum Erstellen einer SQL-Anweisung verwenden.

DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = ' + @city
EXEC (@sqlCommand)

Verwenden von sp_executesql

Mit diesem Ansatz können Sie sicherstellen, dass die an die Abfrage übergebenen Datenwerte die richtigen Datentypen sind, und die Verwendung weiterer Anführungszeichen vermeiden.

DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = 'London'
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = @city'
EXECUTE sp_executesql @sqlCommand, N'@city nvarchar(75)', @city = @city

Referenz

Somnath Muluk
quelle
1

Ich werde darauf hinweisen, dass der Autor in dem Artikel, der in der am besten bewerteten Antwort The Curse and Blessings of Dynamic SQL verlinkt ist, angibt, dass die Antwort nicht darin besteht, Dynamic SQL zu verwenden. Scrollen Sie fast bis zum Ende, um dies zu sehen.

Aus dem Artikel: "Die richtige Methode besteht darin, die Liste in eine Tabelle mit einer benutzerdefinierten Funktion oder einer gespeicherten Prozedur zu entpacken."

Sobald sich die Liste in einer Tabelle befindet, können Sie natürlich einen Join verwenden. Ich konnte die am besten bewertete Antwort nicht direkt kommentieren, daher habe ich diesen Kommentar hinzugefügt.

DavidG
quelle
Dies gibt keine Antwort auf die Frage. Sobald Sie einen ausreichenden Ruf haben, können Sie jeden Beitrag kommentieren . Geben Sie stattdessen Antworten, die nicht vom Fragesteller geklärt werden müssen . - Von der Überprüfung
Sam M
Danke Sam. Ich werde meinen Kommentar mit Details aktualisieren, sobald ich die Vorschläge von Erland Sommarskog umgesetzt habe. Ich werde ihn auch namentlich erwähnen, da er die Antwort verdient.
DavidG