Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 传递NULL参数时,通过表函数返回所有记录_Sql_Sql Server_Where Clause_Sql Function_Sql Null - Fatal编程技术网

Sql 传递NULL参数时,通过表函数返回所有记录

Sql 传递NULL参数时,通过表函数返回所有记录,sql,sql-server,where-clause,sql-function,sql-null,Sql,Sql Server,Where Clause,Sql Function,Sql Null,上面的函数从actions_roles表中返回与提供的@roleid参数匹配的操作列表。但是,actions表中的某些操作在action_roles表中根本不存在。因此,当指定NULL参数时,我希望函数只返回 select*from actions 我尝试使用if语句,但这似乎不适用于内联表函数 CREATE FUNCTION [dbo].[fn_actions] ( @roleid varchar(36) ) RETURNS TABLE AS RETURN select * fro

上面的函数从actions_roles表中返回与提供的@roleid参数匹配的操作列表。但是,actions表中的某些操作在action_roles表中根本不存在。因此,当指定NULL参数时,我希望函数只返回

select*from actions

我尝试使用if语句,但这似乎不适用于内联表函数

CREATE FUNCTION [dbo].[fn_actions]
(
  @roleid varchar(36)
)
RETURNS TABLE
AS
RETURN
  select *
  from actions 
  where action_type_id in (
    select action_type_id
    from action_roles
    where role_id = isnull(@roleid,role_id)
  )

实现这一点的最佳方法是什么?

您只需将参数的空值检查移动到外部查询

这应该满足您的需要,同时简化查询并可能使其更高效(这将更改查询计划器,使其在参数为null时不执行子查询)


注意:正如Vladimir Baranov所评论的,您可能应该将
选项(重新编译)
添加到此查询(它位于最末尾),以强制数据库为每次执行重新计算查询计划,因此当参数为null时,它可能会优化子查询。

这是编写此查询的一个好方法,但是我强烈建议对这种类型的查询使用
选项(重新编译)
。特别是因为最佳执行计划应该根据参数的值有很大的不同。如果没有
选项(重新编译)
,那么优化器必须生成一个对参数的任何可能值都有效的计划,因此无法消除子查询。一篇非常好的文章:由Erland撰写Sommarskog@VladimirBaranov:是的,我认为这是一个很好的观点。我把它添加到我的答案中。谢谢
CREATE FUNCTION [dbo].[fn_actions]
(
  @roleid varchar(36)
)
RETURNS TABLE
AS
RETURN
  IF (@roleid is NULL)
  BEGIN
    select * from actions
  END
  ELSE
    select *
    from actions 
    where action_type_id in (
      select action_type_id
      from action_roles
      where role_id = isnull(@roleid,role_id)
    )
select * 
from actions 
where 
    @roleid is null
    or action_type_id in (select action_type_id from action_roles)