wake-up-neo.net

Deklarieren Sie die Variable für eine Abfragezeichenfolge

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?

75
StealthRT

Es ist möglich, erfordert jedoch die Verwendung von dynamischem SQL.
Ich empfehle zu lesen Der Fluch und der Segen von dynamischem SQL 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)

Dynamic SQL ist nur eine SQL-Anweisung, die vor der Ausführung als Zeichenfolge erstellt wird. So tritt die übliche Stringverkettung auf. Dynamisches SQL ist immer dann erforderlich, wenn Sie etwas in SQL-Syntax tun möchten, das nicht zulässig ist, z.

  • ein einzelner Parameter zur Darstellung der 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 angegebene Beispiel)

EXEC sp_executesql ermöglicht Ihnen die Verwendung von bind/preparstatement-Parametern, damit Sie sich nicht mit einfachen Anführungszeichen/etc für SQL-Injection-Angriffe beschäftigen müssen.

79
OMG Ponies
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)
)
46
hunter

EXEC verwenden

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)

Sp_executesql verwenden

Wenn Sie diesen Ansatz verwenden, können Sie sicherstellen, dass die in die Abfrage übergebenen Datenwerte die richtigen Datentypen sind und keine weiteren Anführungszeichen verwendet werden.

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

2
Somnath Muluk

Ich möchte darauf hinweisen, dass in dem Artikel, der in der am besten bewerteten Antwort verlinkt ist, Der Fluch und der Segen von Dynamic SQL der Autor angibt, dass die Antwort keine dynamische SQL ist. Scrolle fast bis zum Ende, um das zu sehen.

Aus dem Artikel: "Die korrekte 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 nicht direkt zu der am besten bewerteten Antwort Stellung nehmen, deshalb habe ich diesen Kommentar hinzugefügt.

0
DavidG