Zastanawiałem się, czy można to zrobić w MS SQL Server 2005:
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
Czy to się da zrobić?
sql
sql-server
sql-server-2005
tsql
dynamic-sql
StealthRT
źródło
źródło
Odpowiedzi:
Jest to możliwe, ale wymaga użycia dynamicznego SQL. Przed kontynuowaniem
polecam przeczytanie Klątwy i błogosławieństwa dynamicznego SQL ...
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)
Dynamiczny SQL to po prostu instrukcja SQL, złożona jako łańcuch przed wykonaniem. Tak więc następuje zwykłe konkatenowanie ciągów. Dynamiczny SQL jest wymagany, gdy chcesz zrobić coś w składni SQL, co jest niedozwolone, na przykład:
EXEC sp_executesql
pozwala na użycie parametrów bind / readystatement, dzięki czemu nie musisz martwić się o unikanie pojedynczych cudzysłowów / itp. w przypadku ataków typu SQL injection.źródło
DECLARE @theDate DATETIME SET @theDate = '2010-01-01'
Następnie zmień zapytanie, aby używać tej logiki:
źródło
Korzystanie z EXEC
Możesz użyć następującego przykładu do zbudowania instrukcji SQL.
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)
Korzystanie z sp_executesql
Korzystając z tego podejścia, możesz upewnić się, że wartości danych przekazywane do zapytania są poprawnymi typami danych i uniknąć używania większej liczby cudzysłowów.
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
Odniesienie
źródło
Zwrócę uwagę, że w artykule, do którego link znajduje się w najwyżej ocenianej odpowiedzi The Curse and Blessings of Dynamic SQL, autor stwierdza, że odpowiedzią nie jest używanie dynamicznego SQL. Przewiń prawie do końca, aby to zobaczyć.
Z artykułu: „Poprawną metodą jest rozpakowanie listy do tabeli zawierającej funkcję zdefiniowaną przez użytkownika lub procedurę składowaną”.
Oczywiście, gdy lista znajduje się w tabeli, możesz użyć złączenia. Nie mogłem bezpośrednio skomentować najwyżej ocenionej odpowiedzi, więc właśnie dodałem ten komentarz.
źródło