2014-11-11 5 views
0

У меня есть некоторые проблемы с созданием динамического предложения Where.TSQL: динамически строить строку запроса

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

Я пробовал множество вариантов, но мой лучший попробовать до сих пор:

CREATE FUNCTION dbo.GetID (@TaskID varchar(10)) 
       RETURNS Int 
AS 
BEGIN 
    DECLARE @TaskType varchar(10) 
    DECLARE @TaskSubType TinyInt 
    DECLARE @ID Int 
    DECLARE @SQL varchar(400) 

    SELECT @TaskType = TaskType, @TaskSubType = TaskSubType 
    FROM Tasks 
    WHERE TaskID = @TaskID 

    SET @SQL = 'SELECT @ID = ID 
       FROM ZCircuitFaults 
       WHERE TaskType = @TaskType AND ' + 
        CASE WHEN ISNULL(@TaskSubType, '') <> '' 
         THEN '(TaskSubType Is Null OR TaskSubType = CAST(@TaskSubType AS Varchar))' 
        ELSE 'TaskSubType Is Null' 
        END 
exec sp_executesql @SQL 
       , N'@ID Int, @TaskType varchar(10), @TaskSubType tinyint' 
       , @ID, @TaskType, @TaskSubType 
       , @ID = @ID OUTPUT 
RETURN @ID 
END 

Когда я зову:

PRINT dbo.GetID('ABC123') 

Я получаю ошибку:

Only functions and some extended stored procedures can be executed from within a function.

+0

Попробуйте сделать это в хранимую процедуру. – SubqueryCrunch

ответ

1

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

Кроме того, я не понимаю, зачем нужен динамический SQL. Ваш динамический SQL часть может быть просто

SELECT @ID = ID 
       FROM ZCircuitFaults 
       WHERE TaskType = @TaskType AND 
        CASE WHEN ISNULL(@TaskSubType, '') <> '' 
         THEN (TaskSubType Is Null OR TaskSubType = CAST(@TaskSubType AS Varchar)) 
        ELSE TaskSubType Is Null 
        END 

, а затем

RETURN @ID; 

EDIT:

Вся ваша WHERE часть может быть упрощена ниже

WHERE TaskType = @TaskType 
AND (
TaskSubType Is Null 
OR 
TaskSubType = ISNULL(CAST(@TaskSubType AS Varchar), '') 
) 
+0

Спасибо. Вы предлагаете SQL, с которого я начал работать, но вы не можете использовать оператор case, подобный этому в предложении Where. Есть несколько сообщений о работе. В этом случае я получаю «Неправильный синтаксис рядом с ключевым словом« Is »в части THEN. –

+1

@ user1208908, Да, это правильно. Не заметил, что вы не ссылаетесь на столбец в состоянии 'WHERE'; но вы знаете, что вам вообще не нужно условие «case». Весь ваш 'WHERE' может быть упрощен до того, что у меня есть в отредактированном ответе. – Rahul

1

Пер книги в Интернете, вы не можете использовать динамический SQL внутри функции:

User-defined functions cannot make use of dynamic SQL or temp tables. Table variables are allowed.

http://msdn.microsoft.com/en-us/library/ms191320.aspxОграничения и ограничения раздел. Вам нужно будет поместить это в хранимую процедуру.


@Rahul прав, вам не нужен динамический SQL.

Смежные вопросы