#sql #dynamic-sql
#sql #dynamic-sql
Вопрос:
Мне нужна помощь с запросом. В моем запросе я хочу передать имя моей таблицы в качестве параметра. Это мой запрос:
SELECT DISTINCT
CONVERT (varchar, InspectDateTime) AS 'Inspect Date Time',
CONVERT (varchar, SynDateTime) AS 'Sync Date Time',
Employee,
ROUND(OverAllPercentage, 2) AS Grade
FROM
Table_Name
WHERE
(DATEADD(dd, DATEDIFF(dd, 0, InspectDateTime), 0)
BETWEEN
DATEADD(dd, DATEDIFF(dd, 0, @From ), 0) AND
DATEADD(dd, DATEDIFF(dd, 0, @To ), 0))
ORDER BY
'Inspect Date Time'
Здесь я хочу передать Table_Name
в качестве параметра. Пожалуйста, обратите внимание, что этот запрос уже принимает два аргумента в качестве параметра, а именно "@From
» и « @To
«
Комментарии:
1. какую базу данных вы используете? (генерация динамического sql отличается от базы данных к базе данных)
2. Имейте в виду, что ваше предложение order-by будет сортировать даты в алфавитном порядке. Это то, что вы имели в виду?
Ответ №1:
Если вы работаете с MS SQL, вы можете сделать:
CREATE PROCEDURE sp_GetMyStuff
(
@From datetime,
@To datetime,
@TableName nvarchar(100)
)
AS
exec('
SELECT DISTINCT
CONVERT (varchar, InspectDateTime) AS ''Inspect Date Time'',
CONVERT (varchar, SynDateTime) AS ''Sync Date Time'',
Employee,
ROUND(OverAllPercentage, 2) AS Grade
FROM
' @TableName '
WHERE
(DATEADD(dd, DATEDIFF(dd, 0, InspectDateTime), 0)
BETWEEN
DATEADD(dd, DATEDIFF(dd, 0, ' @From '), 0) AND
DATEADD(dd, DATEDIFF(dd, 0, ' @To '), 0))
ORDER BY
1
');
а затем просто вызовите его
sp_GetMyStuff '2011-05-05', '2011-06-05', 'TBL_MYTABLE'
Комментарии:
1. Я не помню сразу. Можете ли вы использовать символ concat с datetime и varchar? Я бы предположил, что нет, но не уверен по памяти.
2. Привет, Balexandre, спасибо за ваш пост. Это сработало нормально после приведения @From и @To в varchar.
Ответ №2:
В SQL Server, если вы хотите «параметризовать» имя таблицы, вы должны использовать динамический SQL
Если это так, вы должны прочитать книгу Эрланда «Проклятие и благословение динамического SQL» в качестве вступления.
Итак, по сути, вам нужно создать свой оператор SQL в виде строки, а затем выполнить его. Другого способа «параметризовать» имя таблицы в инструкции SQL Server T-SQL не существует.
Комментарии:
1. Спасибо marc за ваш комментарий 🙂
Ответ №3:
Хорошо, предполагая, что вы используете SQL Server (судя по DATEADD
и DATEDIFF
функциям), вам нужно
-
создайте объединенную команду sql в виде строки (стараясь не допускать SQL-инъекции: т. Е. вы должны проверить, что ваша
table_name
переменная является допустимым именем таблицы, просмотрев возможные имена формыinformation_schema
и подтвердив и т.д.) -
выполните свой динамический sql, используя
sp_executesql
: http://msdn.microsoft.com/en-us/library/ms188001.aspx
Комментарии:
1. 1 голос за этот ответ за ссылку на sp_executesql. Поскольку poster не только хочет запросить динамическую таблицу, но и передать параметры даты, а также sp_executesql — единственный выход. Ссылка объясняет, как передать @From и @To в динамический оператор.
2. Спасибо davek за ваш комментарий 🙂
Ответ №4:
Спасибо balexandre. Окончательный запрос после незначительной модификации (приведение @From,@To в varchar) является:
CREATE PROCEDURE sp_GetMyStuff
@TableName VARCHAR(128),
@From DATETIME,
@To DATETIME
AS
DECLARE @sql VARCHAR(4000)
SELECT @sql = 'SELECT DISTINCT CONVERT (varchar, InspectDateTime) AS ''Inspect Date Time'', CONVERT (varchar, SynDateTime) AS ''Sync Date Time'', Employee, ROUND(OverAllPercentage, 2) AS Grade
FROM ' @TableName '
WHERE
(DATEADD(dd, DATEDIFF(dd, 0, InspectDateTime), 0) BETWEEN DATEADD(dd, DATEDIFF(dd, 0,''' CAST(@From AS VARCHAR(100)) ''' ), 0)
AND DATEADD(dd, DATEDIFF(dd, 0,''' CAST(@To AS VARCHAR(100)) '''), 0))
ORDER BY ''Inspect Date Time'''
EXEC (@sql)
GO
Комментарии:
1. Если вы публикуете код, XML или образцы данных, пожалуйста , выделите эти строки в текстовом редакторе и нажмите на кнопку «образцы кода» (
{ }
) на панели инструментов редактора, чтобы красиво оформить и выделить синтаксис!