使用表值函数捕获所有查询

时间:2018-10-23 10:14:20

标签: sql sql-server sql-server-2012

我有一个相当长的Sql查询,根据用户的选择需要不同的where子句。

我已经进行了一些搜索,this似乎是最全面的文章。

但是,它没有提到使用表值函数来达到相同效果的选项,对我来说,这似乎是最佳的答案。

我想念什么吗?

这是我用TVF编写的所有查询:

--These paramenters will always be passed
declare @tenantId int = 7;
declare @yesterday DateTime = dateadd(day,datediff(day,1,GETUTCDATE()),0);
declare @tomorrow DateTime = dateadd(day,datediff(day,-1,GETUTCDATE()),0);

--These are optional:
declare @parentId int = 230;  --In this example, @parentId is populated.
declare @ownedById int = null; --In this example, @ownedBy is not populated.


--Simple if statement:
if @parentId is not null
    BEGIN
        if @ownedById is not null
            BEGIN
            Select * from GetItemInfos(@tenantId, @yesterday, @tomorrow)
                where ParentId = @parentId and OwnedById = @ownedById;
            END
        ELSE
            Select * from GetItemInfos(@tenantId, @yesterday, @tomorrow)
                where ParentId = @parentId;
    END
ELSE IF @ownedById is not null
    BEGIN
        Select * from GetItemInfos(@tenantId, @yesterday, @tomorrow)
                where OwnedById = @ownedById;
    END
ELSE
    Select * from GetItemInfos(@tenantId, @yesterday, @tomorrow);

这是TVF:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION GetItemInfos 
(   
    @tenantId int,
    @yesterday DateTime,
    @tomorrow DateTime

)
RETURNS TABLE 
AS
RETURN 
(

Select i.Id,
    i.AssignedToId,
    i.ParentId,
    i.OwnedById,
    i.Budget,
    i.CloseDate,
    i.CloseStatusId,

    AssignedToName = Concat(anu.FirstName, ' ', anu.LastName),
    OwnedByName = Concat(anu2.FirstName, ' ', anu2.LastName),
    CloseStatusName = cs.Name,

    i.ItemTypeId,

    ItemTypeIcon = it.Icon,

    i.ImportanceTypeId,
    ImportanceTypeDescription = ImportanceTypes.Description,

    i.EntityStatusId,
    i.DueDate,
    IsOverdue = 
        case when i.CloseStatusId = 1 and i.DueDate <= @yesterday then Cast(1 as bit)
        else Cast(0 as bit)
        end,
    IsDue =
        case when i.CloseStatusId = 1 and i.DueDate >= @yesterday and i.DueDate < @tomorrow then cast(1 as bit)
        else Cast(0 as bit)
        end,
    IsClosed = case when (i.CloseStatusId != 1) then cast(1 as bit) else cast(0 as bit) end,
    i.Cost,
    ItemTypeShowProperties = it.ShowProperties,
    ItemTypeSortOrder = it.SortOrder,
    PriorityTypeDescription =  PriorityTypes.Description,
    PriorityTypeSortOrder = PriorityTypes.SortOrder,
    i.Name,
    i.PriorityTypeId,
    Progress = Convert(nvarchar, i.Progress) + '%',
    i.SortOrder,
    i.StartDate,
    StatusTypeName = StatusTypes.Name,
    i.TimeEstimate,
    TimeScaleTypeName = TimeScaleTypes.Name 

 from Items i 

 left join AppUsers au
 on i.AssignedToId = au.Id
    left join AspNetUsers anu
    on au.AspNetUserId = anu.id

 left join AppUsers au2
 on i.OwnedById = au2.Id
    left join AspNetUsers anu2
    on au2.AspNetUserId = anu2.id

 left join CloseStatuses cs
 on i.CloseStatusId = cs.id

 left join ItemTypes it
 on i.ItemTypeId = it.Id

 left join ImportanceTypes 
 on i.ImportanceTypeId = ImportanceTypes.Id

 left join PriorityTypes 
 on i.PriorityTypeId = PriorityTypes.Id

 left join StatusTypes
 on i.StatusTypeId = StatusTypes.Id

 left join TimeScaleTypes
 on i.TimeScaleTypeId = TimeScaleTypes.Id

 where  i.TenantId = @tenantid 

)
GO

编辑 根据评论,这似乎是编写此内容的最佳方法:

Select * from GetItemInfos(@tenantId, @yesterday, @tomorrow)
    where (@parentId is null or ParentId = @parentId) and (@ownedById is null or OwnedById = @ownedById) OPTION(RECOMPILE)

0 个答案:

没有答案