内联表值函数中的 IF Else

Posted

技术标签:

【中文标题】内联表值函数中的 IF Else【英文标题】:IF Else inside Inline Table Valued Functions 【发布时间】:2016-09-05 13:53:30 【问题描述】:

是否可以使用 If Else Inside 内联表值函数。我有一个标量函数,我正在使用 If Else Condition 但是,该查询需要太多时间来执行,我想将它转换为内联表值函数。请建议我该怎么做。

ALTER FUNCTION [dbo].[TestFunctionFindSum]  
(  
 @ProductID bigint,  
 @TotalType nvarchar(200),   
 @OwnerUserID bigint,  
 @OrganizationID bigint,  
 @BusinessUnitID bigint,  
 @InventoryID bigint  
)  
RETURNS decimal(32,9)  
AS  
BEGIN  
 -- declare the return variable here  
 declare @OutputValue decimal(32,9)   
Declare @locationValue int =0 

 ---------------------------------------------------------------------  
 -- Getting Inventory Items Total as per the Total Type supplied  
 ---------------------------------------------------------------------  

 IF @TotalType = 'QuantityOnHand'     
 BEGIN  
  set @OutputValue = isnull((select sum(ii.[QuantityOnHand])   
           from dbo.InventoryItems ii, Inventory i               
           where   ii.ActiveStatus=1  
           and ii.ProductID = @ProductID  
            and ii.InventoryID = i.InventoryID  
        AND i.OwnerUserGroupID = case @OwnerUserID   
       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
        AND i.OrganizationID = case @OrganizationID  
       when 0 then i.OrganizationID else @OrganizationID end  
        AND i.BusinessUnitID = case @BusinessUnitID  
       when 0 then i.BusinessUnitID else @BusinessUnitID end  
        AND i.InventoryID = case @InventoryID  
       when 0 then i.InventoryID else @InventoryID end), 0.00)  
 END  
 ELSE IF @TotalType = 'QuantityBooked'  
    BEGIN   
  set @OutputValue = isnull((select sum(ii.QuantitySold)   
           from dbo.InventoryItems ii, Inventory i               
           where   ii.ActiveStatus=1  
           and ii.ProductID = @ProductID  
            and ii.InventoryID = i.InventoryID  
        AND i.OwnerUserGroupID = case @OwnerUserID   
       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
        AND i.OrganizationID = case @OrganizationID  
       when 0 then i.OrganizationID else @OrganizationID end  
        AND i.BusinessUnitID = case @BusinessUnitID  
       when 0 then i.BusinessUnitID else @BusinessUnitID end  
        AND i.InventoryID = case @InventoryID  
       when 0 then i.InventoryID else @InventoryID end), 0.00)  
 END   
 ELSE IF @TotalType = 'ProjectedQuantityOnHand'  
    BEGIN   
  set @OutputValue = isnull((select (sum(ii.QuantityOnHand) - sum(ii.QuantitySold))  
           from dbo.InventoryItems ii, Inventory i               
           where   ii.ActiveStatus=1  
           and ii.ProductID = @ProductID  
            and ii.InventoryID = i.InventoryID  
        AND i.OwnerUserGroupID = case @OwnerUserID   
       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
        AND i.OrganizationID = case @OrganizationID  
       when 0 then i.OrganizationID else @OrganizationID end  
        AND i.BusinessUnitID = case @BusinessUnitID  
       when 0 then i.BusinessUnitID else @BusinessUnitID end  
        AND i.InventoryID = case @InventoryID  
       when 0 then i.InventoryID else @InventoryID end), 0.00)  
 END   
 return @OutputValue  

END  

上面是我的标量函数..知道如何根据内联表值函数找到记录。

我在尝试什么

CREATE FUNCTION [dbo].[TestFunctionFindSum](@ProductID bigint,  
 @TotalType nvarchar(200),   
 @OwnerUserID bigint,  
 @OrganizationID bigint,  
 @BusinessUnitID bigint,  
 @InventoryID bigint  )
RETURNS TABLE
AS RETURN
IF @TotalType = 'QuantityOnHand'     
 BEGIN  
   isnull((select sum(ii.[QuantityOnHand])   
           from dbo.InventoryItems ii, Inventory i               
           where   ii.ActiveStatus=1  
           and ii.ProductID = @ProductID  
            and ii.InventoryID = i.InventoryID  
        AND i.OwnerUserGroupID = case @OwnerUserID   
       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
        AND i.OrganizationID = case @OrganizationID  
       when 0 then i.OrganizationID else @OrganizationID end  
        AND i.BusinessUnitID = case @BusinessUnitID  
       when 0 then i.BusinessUnitID else @BusinessUnitID end  
        AND i.InventoryID = case @InventoryID  
       when 0 then i.InventoryID else @InventoryID end), 0.00)  
 END  
GO

【问题讨论】:

不,你不能使用 if 因为你只能有一个语句。您需要在 select 子句中有一个 case 语句来选择正确的总和,可能使用派生表或 CTE 以使其更清晰。 【参考方案1】:

您可以使用 CASE 语句作为,

CREATE FUNCTION [dbo].[TestFunctionFindSum](@ProductID bigint,  
 @TotalType nvarchar(200),   
 @OwnerUserID bigint,  
 @OrganizationID bigint,  
 @BusinessUnitID bigint,  
 @InventoryID bigint  )
RETURNS TABLE
AS RETURN
SELECT 
    CASE WHEN @TotalType = 'QuantityOnHand' THEN 
                isnull((select sum(ii.[QuantityOnHand])   
                        from dbo.InventoryItems ii, Inventory i               
                        where   ii.ActiveStatus=1  
                        and ii.ProductID = @ProductID  
                        and ii.InventoryID = i.InventoryID  
                        AND i.OwnerUserGroupID = case @OwnerUserID   
                       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
                        AND i.OrganizationID = case @OrganizationID  
                       when 0 then i.OrganizationID else @OrganizationID end  
                        AND i.BusinessUnitID = case @BusinessUnitID  
                       when 0 then i.BusinessUnitID else @BusinessUnitID end  
                        AND i.InventoryID = case @InventoryID  
                       when 0 then i.InventoryID else @InventoryID end), 0.00)  
        WHEN @TotalType = 'QuantityBooked'  THEN 
                isnull((select sum(ii.QuantitySold)   
                        from dbo.InventoryItems ii, Inventory i               
                        where   ii.ActiveStatus=1  
                        and ii.ProductID = @ProductID  
                        and ii.InventoryID = i.InventoryID  
                        AND i.OwnerUserGroupID = case @OwnerUserID   
                       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
                        AND i.OrganizationID = case @OrganizationID  
                       when 0 then i.OrganizationID else @OrganizationID end  
                        AND i.BusinessUnitID = case @BusinessUnitID  
                       when 0 then i.BusinessUnitID else @BusinessUnitID end  
                        AND i.InventoryID = case @InventoryID  
                       when 0 then i.InventoryID else @InventoryID end), 0.00)  
        WHEN @TotalType = 'ProjectedQuantityOnHand'  THEN
                isnull((select (sum(ii.QuantityOnHand) - sum(ii.QuantitySold))  
                        from dbo.InventoryItems ii, Inventory i               
                        where   ii.ActiveStatus=1  
                        and ii.ProductID = @ProductID  
                        and ii.InventoryID = i.InventoryID  
                        AND i.OwnerUserGroupID = case @OwnerUserID   
                       when 0 then i.OwnerUserGroupID else @OwnerUserID end  
                        AND i.OrganizationID = case @OrganizationID  
                       when 0 then i.OrganizationID else @OrganizationID end  
                        AND i.BusinessUnitID = case @BusinessUnitID  
                       when 0 then i.BusinessUnitID else @BusinessUnitID end  
                        AND i.InventoryID = case @InventoryID  
                       when 0 then i.InventoryID else @InventoryID end), 0.00)  
        END AS OutputValue
 GO  

【讨论】:

以上是关于内联表值函数中的 IF Else的主要内容,如果未能解决你的问题,请参考以下文章

SQL 中内联表值函数的性能影响

内联表值函数中 SELECT * 的性能

帮助! - SQL - IF Else IF 逻辑用于返回 Containstable 选择

多语句表值函数与内联表值函数

sqlserver中的表值函数和标量值函数

内联表值函数以“用户”身份执行