从逗号分隔的字符串输入中获取数据

时间:2014-03-13 13:23:01

标签: sql-server-2008

我有一个存储过程,其中输入是逗号分隔的字符串,例如'12341,34567,12446,12997',并且不确定输入字符串是否始终携带数字数据。它可能是'12341,34as67,12 $ 46,1we97'所以我需要验证它们并仅使用查询中的有效数据。

说我的查询是(OrderCode列是int类型的地方)

select * from dbo.DataCollector where OrderCode in (12341,34567,12446,12997)

或只有有效数据,如果其他无效

select * from dbo.DataCollector where OrderCode in (12341)

对于这种情况,这将是一个很好的解决方案。

1 个答案:

答案 0 :(得分:1)

在SQl-Server 2005中也可以使用的一种方法是创建一个分割功能,然后你可以使用ISNUMERIC检查它是否是一个数字:

DECLARE @Input VARCHAR(MAX) = '12341,34as67,12$46,1we97' 

SELECT i.Item FROM dbo.Split(@Input, ',')i
WHERE  IsNumeric(i.Item) = 1

Demo

您的完整查询:

select * from dbo.DataCollector 
where OrderCode in ( SELECT i.Item FROM dbo.Split(@Input, ',')i
                     WHERE  IsNumeric(i.Item) = 1 )

这是我使用的分割功能:

CREATE FUNCTION [dbo].[Split]
(
    @ItemList NVARCHAR(MAX), 
    @delimiter CHAR(1)
)
RETURNS @ItemTable TABLE (Item VARCHAR(250))  
AS      

BEGIN    
    DECLARE @tempItemList NVARCHAR(MAX)
    SET @tempItemList = @ItemList

    DECLARE @i INT    
    DECLARE @Item NVARCHAR(4000)

    SET @i = CHARINDEX(@delimiter, @tempItemList)

    WHILE (LEN(@tempItemList) > 0)
    BEGIN
        IF @i = 0
            SET @Item = @tempItemList
        ELSE
            SET @Item = LEFT(@tempItemList, @i - 1)
        INSERT INTO @ItemTable(Item) VALUES(@Item)
        IF @i = 0
            SET @tempItemList = ''
        ELSE
            SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i)
        SET @i = CHARINDEX(@delimiter, @tempItemList)
    END 
    RETURN
END  

编辑根据Damien的评论ISNUMERIC有问题。您可以使用此函数检查它是否为实数:

CREATE FUNCTION dbo.IsInteger(@Value VarChar(18))
RETURNS Bit
AS 
BEGIN

  RETURN IsNull(
     (Select Case When CharIndex('.', @Value) > 0 
                  Then Case When Convert(int, ParseName(@Value, 1)) <> 0
                            Then 0
                            Else 1
                            End
                  Else 1
                  End
      Where IsNumeric(@Value + 'e0') = 1), 0)    
END

这是达米安的另一个例子,&#34;坏&#34;输入包含£0d0

Demo