Sql server TSQL:动态生成查询字符串

Sql server TSQL:动态生成查询字符串,sql-server,tsql,case,where-clause,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

我在创建动态
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
我得到一个错误:

只有函数和一些扩展存储过程才能从函数中执行


根据联机丛书,您不能在函数中使用动态SQL:

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

限制和限制部分。您需要将其放入存储过程中



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

问题是您不能从函数中使用动态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
编辑:

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

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

请尝试在存储过程中执行此操作。谢谢。您提出的SQL是我开始使用的SQL,但是您不能在where子句中使用这样的case语句。有几个关于工作环境的帖子。在这个例子中,我在THEN部分得到了一个“关键字”Is附近的不正确语法。@user1208908,是的,它是正确的。没有注意到您没有引用
WHERE
条件中的列;但是你知道你实际上根本不需要一个
案例
条件。您的整个
WHERE
可以简化为我在编辑的答案中的内容。
RETURN @ID;
WHERE TaskType = @TaskType 
AND (
TaskSubType Is Null 
OR 
TaskSubType = ISNULL(CAST(@TaskSubType AS Varchar), '')
)