Как мне указать предложение FROM инструкции SELECT из параметра UDF
-
20-08-2019 - |
Вопрос
В приложении, над переносом которого я работаю в Интернет, в настоящее время мы динамически получаем доступ к различным таблицам во время выполнения от запуска к запуску на основе указанной строки "шаблона".Я хотел бы перенести бремя выполнения этого обратно на базу данных теперь, когда мы переходим на SQL server, поэтому мне не нужно возиться с динамическим представлением сетки.Я подумал о написании UDF с табличным значением с параметром для имени таблицы и параметром для предложения query WHERE .
Я ввел следующее для своего UDF, но, очевидно, это не работает.Есть ли какой-нибудь способ взять varchar или строку какого-либо типа и получить ссылку на таблицу, которая может работать в предложении FROM?
CREATE FUNCTION TemplateSelector
(
@template varchar(40),
@code varchar(80)
)
RETURNS TABLE
AS
RETURN
(
SELECT * FROM @template WHERE ProductionCode = @code
)
Или какой-то другой способ получения результирующего набора, аналогичного по концепции этому.В основном все записи в таблице указаны с помощью varchar @template с соответствующим ProductionCode для @code.
Я получаю сообщение об ошибке "Необходимо объявить табличную переменную "@template"", так что SQL server, вероятно, то, что я пытаюсь выбрать из табличной переменной.
При редактировании:Да, мне не нужно делать это в функции, я могу запускать сохраненные процедуры, просто я раньше не писал ни одной из них.
Решение
CREATE PROCEDURE TemplateSelector
(
@template varchar(40),
@code varchar(80)
)
AS
EXEC('SELECT * FROM ' + @template + ' WHERE ProductionCode = ' + @code)
Это работает, хотя это и не UDF.
Другие советы
Единственный способ сделать это - с помощью команды exec.
Кроме того, вы должны переместить его в сохраненный процесс вместо функции.Очевидно, функции не могут выполнять динамический sql.
Единственный способ, которым это было бы возможно, - использовать динамический SQL, однако динамический SQL не поддерживается SQLServer внутри функции.
Мне жаль говорить, но я совершенно уверен, что это НЕВОЗМОЖНО сделать в рамках функции.
Если бы вы работали с хранимыми процедурами, это было бы возможно.
Также следует отметить, что, заменив имя таблицы в запросе, вы лишили SQL Server возможности кэшировать план выполнения запроса.Это в значительной степени сводит преимущество использования UDF или SP к нулю.С таким же успехом вы могли бы просто вызвать SQL-запрос напрямую.
У меня есть конечное число таблиц, к которым я хочу иметь возможность обращаться, поэтому я мог бы написать что-нибудь, используя IF , которое проверяет @template на совпадения с несколькими значениями и для каждого совпадения выполняется
SELECT * FROM TEMPLATENAME WHERE ProductionCode = @code
Похоже, что это лучший вариант
Если у вас есть множество таблиц с идентичной структурой, это обычно означает, что вы не оформили свою базу данных в обычной форме.Вы должны объединить их в одну таблицу.Возможно, вам потребуется присвоить этой таблице еще один столбец атрибутов, чтобы различать наборы данных.