标量函数一起使用超时

时间:2013-05-16 17:00:21

标签: sql sql-server sql-server-2008 tsql

单独使用以下任一功能表现良好(dbo.getCorrectInventoryKey(Inventory_Key) and dbo.getEntityFullName2(Inventory_Key, '.')),但在一起使用时(dbo.getEntityFullName2(dbo.getCorrectInventoryKey(Inventory_Key), '.')),查询永远不会返回...

CREATE    function [dbo].[getEntityFullName2] (@inventory_Key varchar(100),@delim varchar(5)) returns varchar(1000) as
begin

    declare
    @continue   bit,            /* loop controller */
    @dIndex     int,            /* delimeter index character position */
    @key        varchar(100),   /* temp var used to hold one key through the loop */
    @retStr     varchar(1000)   /* return string (full item name) */


    /* set the default values for our local variables */
    set @continue = 1
    set @dIndex = 0
    set @retStr = ''


    /* loop until we make it through all items in the key */
    while(@continue = 1) begin
        /* return the next index of the '-' character */
        set @dIndex = charIndex('-',@inventory_Key,@dIndex+1)

        /* if we didn't find another occurance, then we know we are done looping */
        if(@dIndex = 0) begin
            set @dIndex = len(@inventory_Key)
            set @continue = 0
        end

        /* set the current key value */
        set @key = left(@inventory_Key,@dIndex)
        /* check to see if we need to strip off a right '-' character */
        set @key = case right(@key,1) when '-' then left(@key,len(@key)-1) else @key end 

        /* concat our return string with the value from the DB */
        set @retStr = @retStr + isNull((select entity from dbo.tbl_Inventory_Entities where inventory_key LIKE (@key)),'[not defined]') + @delim
    end

    /* trim off the extra '-' character we inserted */
    set @retStr = left(@retStr,len(@retStr)-len(@delim))

    /* return the value */
    return @retStr 
end

CREATE FUNCTION [dbo].[getCorrectInventoryKey](@key varchar(100))
RETURNS varchar(100)
AS
BEGIN

DECLARE @returnkey varchar(100)

SELECT @returnkey = CASE
WHEN @key LIKE ('1001-2002-3003-4016%') OR @key LIKE ('1010-2002-3003-4016%') OR @key LIKE ('1020-2002-3003-4016%') THEN '1001-2002-3003-4016'
WHEN (@key LIKE ('1001-2002-3003-4005') OR @key LIKE ('1001-2002-3003-4006')) OR (@key LIKE ('1010-2002-3003-4005') OR @key LIKE ('1010-2002-3003-4006')) OR (@key LIKE ('1020-2002-3003-4005') OR @key LIKE ('1020-2002-3003-4006')) THEN '1001-2002-3003'
WHEN @key LIKE ('1001-2002-3004%') OR @key LIKE ('1010-2002-3004%') OR @key LIKE ('1020-2002-3004%') THEN '1001-2002-3004'
WHEN @key LIKE ('1001-2002-3005%') OR @key LIKE ('1010-2002-3005%') OR @key LIKE ('1020-2002-3005%') THEN '1001-2002-3005'
WHEN @key LIKE ('1001-2002-3007%') OR @key LIKE ('1010-2002-3007%') OR @key LIKE ('1020-2002-3007%') THEN '1001-2002-3007'
WHEN @key LIKE ('1001-2001-3001%') OR @key LIKE ('1010-2001-3001%') OR @key LIKE ('1020-2001-3001%') THEN '1001-2001-3001'
WHEN @key LIKE ('1001-2002-3006%') OR @key LIKE ('1010-2002-3006%') OR @key LIKE ('1020-2002-3006%') THEN '1001-2002-3006'
WHEN @key LIKE ('1001-2001-3020%') OR @key LIKE ('1010-2001-3020%') OR @key LIKE ('1020-2001-3020%') THEN '1001-2001-3020'
WHEN @key LIKE ('1003-2010%') THEN '1003-2010'
ELSE NULL
END

RETURN @returnkey

END

1 个答案:

答案 0 :(得分:1)

你确定你的函数getCorrectInventoryKey在每种情况下都返回非空值吗?看起来它至少可能它返回一个NULL(基于CASE语句的ELSE子句),在这种情况下你的函数getEntityFullName2将进入一个无限循环。如果@inventory_Key参数为NULL,则

set @dIndex = charIndex('-',@inventory_Key,@dIndex+1)

将@dIndex设置为NULL,并且以下代码将不会执行:

if(@dIndex = 0) begin
    set @dIndex = len(@inventory_Key)
    set @continue = 0
end

更改

set @dIndex = charIndex('-',@inventory_Key,@dIndex+1)

set @dIndex = ISNULL(charIndex('-',@inventory_Key,@dIndex+1), 0)