Как предоставить предложение FROM оператора SELECT из параметра UDF - PullRequest
1 голос
/ 08 декабря 2008

В приложении, над которым я работаю над портированием в Интернет, в настоящее время мы динамически обращаемся к различным таблицам во время выполнения от запуска к запуску на основе указанной строки «template». Я хотел бы перенести бремя выполнения этого назад на базу данных сейчас, когда мы переходим на SQL-сервер, поэтому мне не нужно связываться с динамическим GridView. Я подумал о написании табличной UDF с параметром для имени таблицы и параметром запроса 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, вероятно, пытается выбрать из табличной переменной то, что я пытаюсь выбрать.

При редактировании: Да, мне не нужно делать это в функции, я могу запускать сохраненные процессы, я просто не писал ни одного из них раньше.

Ответы [ 6 ]

4 голосов
/ 08 декабря 2008
CREATE PROCEDURE TemplateSelector 
(   
    @template varchar(40),
    @code varchar(80)
)

AS
EXEC('SELECT * FROM ' + @template + ' WHERE ProductionCode = ' + @code)

Это работает, хотя это не UDF.

2 голосов
/ 08 декабря 2008

Единственный способ сделать это с помощью команды exec.

Кроме того, вы должны переместить его в сохраненный процесс вместо функции. Видимо функции не могут выполнять динамические sql.

0 голосов
/ 08 декабря 2008

Если у вас есть множество таблиц с одинаковой структурой, это обычно означает, что вы не проектировали свою базу данных в обычной форме. Вы должны объединить их в одну таблицу. Возможно, вам придется дать этой таблице еще один столбец атрибутов, чтобы различать наборы данных.

0 голосов
/ 08 декабря 2008

У меня есть конечное количество таблиц, к которым я хочу обратиться, поэтому я мог бы написать что-нибудь, используя IF, который проверяет @template на совпадения с количеством значений и для каждого совпадения запускает

SELECT * FROM TEMPLATENAME WHERE ProductionCode = @code

Похоже, это лучший вариант

0 голосов
/ 08 декабря 2008

Кроме того, следует отметить, что, заменяя имя таблицы в запросе, вы уничтожили возможность SQL Server кэшировать план выполнения для запроса. Это в значительной степени уменьшает преимущество использования UDF или SP до нуля. Вы также можете просто вызвать SQL-запрос напрямую.

0 голосов
/ 08 декабря 2008

Единственный способ сделать это возможно с помощью динамического SQL, однако SqlServer внутри функции не поддерживает динамический SQL.

Мне жаль говорить, что я совершенно уверен, что это невозможно сделать в функции.

Если бы вы работали с хранимыми процедурами, это было бы возможно.

...