TSQL:动态构建查询字符串

时间:2014-11-11 14:51:57

标签: sql-server tsql case where-clause

我在创建动态Where子句时遇到了一些麻烦。

我想将一个参数传递给一个函数,然后使用该参数从数据库中检索值并在我的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')

我收到错误:

  

只能在函数内执行函数和一些扩展存储过程。

2 个答案:

答案 0 :(得分:2)

问题是您无法在函数中使用动态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;

修改

您的整个WHERE部分可以简化为

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

答案 1 :(得分:1)

在线图书,你不能在函数中使用动态SQL:

  

用户定义的函数无法使用动态SQL或临时表。   允许使用表变量。

http://msdn.microsoft.com/en-us/library/ms191320.aspx 限制和限制部分。您需要将其放入存储过程中。


@Rahul是对的,你不需要动态SQL。