如何将一列中的多个值与存储过程中的分隔字符串进行比较

时间:2012-06-11 23:42:36

标签: sql-server arrays stored-procedures

好的,第一个问题,你们知道你知道多少,所以请温柔......

我试图传入一个分隔的字符串并将其转换为存储过程中的数组,然后使用该数组来检查列中的值。这是捕获。我正在尝试使用预先存在的表,它检查一个关联并将其展开以允许多个关联。

所以列annAssociations可能有三个id,4,16,32,但是我需要检查它是否属于被查询的groupId,6,12,32。由于其中一个值匹配,因此应返回该行。

这是存在的程序。

CREATE PROCEDURE [dbo].[sp_annList] 
-- Date Range of Announcements.
@dateBegin datetime,
@dateEnd datetime,
    -- Announcement type and associations.
@annType varchar(50),
@annAssociation varchar(255)

AS
BEGIN

-- Set the SELECT statement for the announcements.
SET NOCOUNT ON;
-- See if this should be a limited query
IF @annAssociation <> ''
    Begin
        SELECT * 
        FROM announcements
        WHERE (date1 <= @dateEnd AND date2 >= @dateBegin) -- See if the announcement falls in the date range.
            AND annType = @annType -- See if the announcement is the right type.
            AND annAssociations LIKE (select SplitText from dbo.fnSplit(@annAssociation, ','))
        ORDER BY title
    END
Else 
    Begin
        SELECT *
        FROM announcements
        WHERE (date1 <= @dateEnd AND date2 >= @dateBegin)
            AND annType = @annType
        ORDER BY title
    End
END

这是我用来转换分隔字符串并将其存储在临时表中的方法。

CREATE Function [dbo].[fnSplit](@text text, @delimitor nchar(1))

RETURNS
@table TABLE
(
[Index] int Identity(0,1),
[SplitText] varchar(10)
)
AS

BEGIN
declare @current varchar(10)
declare @endIndex int
declare @textlength int
declare @startIndex int

set @startIndex = 1

if(@text is not null)
begin
    set @textLength = datalength(@text)

    while(1=1)
    begin
        set @endIndex = charindex(@delimitor, @text, @startIndex)

        if(@endIndex != 0)
        begin
            set @current = substring(@text,@startIndex, @endIndex - @StartIndex)
            Insert Into @table ([SplitText]) values(@current)
            set @startIndex = @endIndex + 1   
        end
        else
        begin
            set @current = substring(@text, @startIndex, datalength(@text)-@startIndex+1)
            Insert Into @table ([SplitText]) values(@current)
            break
        end
    end

end

return
END

很抱歉这个问题很长。我只想获得所有信息。我已经研究了几天,我要么不知道在哪里看,要么遗漏了一些明显的东西。

1 个答案:

答案 0 :(得分:0)

你可能不会比这种方法获得更好的性能(你可能会看到使用CLR分割功能获得更好的性能,但是在3或4个项目中你看不出太大差异):

SELECT * 
  FROM announcements AS a
  WHERE ...
  AND EXISTS (SELECT 1 FROM dbo.fnSplit(@annAssociation) AS n
    WHERE ',' + a.annList + ',' LIKE '%,' + n.SplitText + ',%');

这里的关键是你只需要拆分其中一个列表。

真的应该停止在annAssocations列中存储多个值。每个id都是一个单独的数据,应该单独存储(除了更好地符合规范化,它将使这样的查询更简单)。