Поймать все запросы с помощью табличной функции - PullRequest
0 голосов
/ 23 октября 2018

У меня довольно длинный Sql-запрос, для которого нужны разные выражения where в зависимости от выбора пользователя.

Я провел некоторый поиск, и эта представляется наиболее полной статьей по этому вопросу..

Однако здесь не упоминается возможность использования табличной функции для достижения того же эффекта, и мне кажется, что это наиболее оптимальный ответ.

Я пропустилчто-то?

Вот мой улов всех запросов, написанных с 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

EDIT Судя по комментариям, это лучший способ написать это:

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