【问题标题】:Split value pairs and a create table using UDF使用 UDF 拆分值对和创建表
【发布时间】:2011-10-04 04:15:16
【问题描述】:

我一直在尝试编写一个表值函数,它以值对作为参数并返回一个包含两列的表。

下面是我想要做的函数签名。

FUNCTION [dbo].[ValuePairParser]( @DelimitedValuePairs VARCHAR(MAX),
                                  @Delimiter CHAR(1), 
                                  @ValuePairDelimiter CHAR(1) ) 
  RETURNS @ValuePairTable
  TABLE ( Id INT, Code INT ) 

我想调用如下方法

@ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3, 1000:230, 130:120,'

ValuePairParser (@ValuePairs, ',', ':')

你有什么好的方法可以拆分 ValuePairs 字符串并创建一个包含两列的表吗?

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql user-defined-functions


    【解决方案1】:
    CREATE FUNCTION [dbo].[SplitWithPairs]
    (
        @List NVARCHAR(MAX),
        @MajorDelimiter VARCHAR(3) = ',',
        @MinorDelimiter VARCHAR(3) = ':'
    )
    RETURNS @Items TABLE
    (
        Position  INT IDENTITY(1,1) NOT NULL,
        LeftItem  INT NOT NULL,
        RightItem INT NOT NULL
    )
    AS
    BEGIN
        DECLARE
            @Item      NVARCHAR(MAX),
            @LeftItem  NVARCHAR(MAX),
            @RightItem NVARCHAR(MAX),
            @Pos       INT;
    
        SELECT
            @List = @List + ' ',
            @MajorDelimiter = LTRIM(RTRIM(@MajorDelimiter)),
            @MinorDelimiter = LTRIM(RTRIM(@MinorDelimiter));
    
        WHILE LEN(@List) > 0
        BEGIN
            SET @Pos = CHARINDEX(@MajorDelimiter, @List);
    
            IF @Pos = 0 
                SET @Pos = LEN(@List) + LEN(@MajorDelimiter);
    
            SELECT
                @Item = LTRIM(RTRIM(LEFT(@List, @Pos - 1))),
                @LeftItem = LTRIM(RTRIM(LEFT(@Item,
                CHARINDEX(@MinorDelimiter, @Item) - 1))),
                @RightItem = LTRIM(RTRIM(SUBSTRING(@Item,
                CHARINDEX(@MinorDelimiter, @Item)
                + LEN(@MinorDelimiter), LEN(@Item))));
    
            INSERT @Items(LeftItem, RightItem)
                SELECT @LeftItem, @RightItem;
    
            SET @List = SUBSTRING(@List,
                @Pos + LEN(@MajorDelimiter), DATALENGTH(@List));
        END
        RETURN;
    END
    GO
    
    DECLARE @ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3,1000:230, 130:120,';
    
    SELECT LeftItem, RightItem
      FROM dbo.SplitWithPairs(@ValuePairs, ',', ':')
      ORDER BY Position;
    GO
    

    【讨论】:

    • 喜欢postition的概念
    • 很好的答案!谢谢!
    【解决方案2】:
    create function ValuePairParser(@DelimitedValuePairs varchar(MAX),
                                    @Delimiter char(1), 
                                    @ValuePairDelimiter char(1)) 
    returns @ValuePairTable table(Id int, Code int) as
    begin 
      with Split(ValuePair, Rest) as
      (
        select left(@DelimitedValuePairs, charindex(@Delimiter, @DelimitedValuePairs)-1),
               stuff(@DelimitedValuePairs, 1, charindex(@Delimiter, @DelimitedValuePairs), '')
        where charindex(@Delimiter, @DelimitedValuePairs) > 0
        union all
        select left(Rest, charindex(@Delimiter, Rest)-1),
               stuff(Rest, 1, charindex(@Delimiter, Rest), '')
        from Split         
        where charindex(@Delimiter, Rest) > 0
      )               
      insert into @ValuePairTable
      select left(ValuePair, charindex(@ValuePairDelimiter, ValuePair)-1),
             stuff(ValuePair, 1, charindex(@ValuePairDelimiter, ValuePair), '')
      from Split                 
      option (maxrecursion 0)
    
      return
    end
    

    【讨论】:

    • @Mikael:谢谢,这看起来很棒! +1
    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 2019-03-11
    • 2022-12-04
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    相关资源
    最近更新 更多