1

我有SplitDictionary功能:

ALTER FUNCTION [dbo].[SplitDictionary]
(    
    @RowKey NVARCHAR(MAX),
    @RowData NVARCHAR(MAX),
    @Delimeter NVARCHAR(2)
)
RETURNS @RtnValue TABLE 
(
    ID INT IDENTITY(1,1),
    keyValue nvarchar(max), 
    Data NVARCHAR(MAX)
) 
AS
BEGIN 
    DECLARE @Iterator INT
    SET @Iterator = 1

    DECLARE @FoundIndex INT
    SET @FoundIndex = CHARINDEX(@Delimeter,@RowData)
    declare @keyFoundIndex int
    set @keyFoundIndex=charindex(@Delimeter, @RowKey)


    WHILE (@FoundIndex>0)
    BEGIN
        INSERT INTO @RtnValue (keyValue, data)
        SELECT KeyValue=LTRIM(RTRIM(SUBSTRING(@RowKey, 1, @FoundIndex - 1))),
            Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))


        SET @RowKey=substring(@RowKey, @FoundIndex + datalength(@Delimeter)/2, len(@RowKey))


        SET @RowData = SUBSTRING(@RowData,@FoundIndex + DATALENGTH(@Delimeter) / 2,LEN(@RowData))

        SET @Iterator = @Iterator + 1
        SET @FoundIndex = CHARINDEX(@Delimeter, @RowData)
    END

    INSERT INTO @RtnValue (keyValue, Data)
    SELECT keyValue=ltrim(rtrim(@RowKey)), Data = LTRIM(RTRIM(@RowData))

    RETURN
END

当我使用此功能时:

SELECT ID, keyValue, Data from dbo.SplitDictionary('10,1','20,30', ',')

结果是:


1 10 20

2 1 30

这是真的

当我使用此功能时:

SELECT ID, keyValue, Data from dbo.SplitDictionary('1,1','20,30', ',')

结果是:


1 1, 20

2 空 30

这是假的

如何修复存储过程中的第二次调用?

4

2 回答 2

0

这应该可以,试试吧:

ALTER FUNCTION [dbo].[SplitDictionary]
(    
    @RowKey NVARCHAR(MAX),
    @RowData NVARCHAR(MAX),
    @Delimeter NVARCHAR(2)
)
RETURNS @RtnValue TABLE 
(
    ID INT IDENTITY(1,1),
    keyValue nvarchar(max), 
    Data NVARCHAR(MAX)
) 
AS
BEGIN 
    DECLARE @Iterator INT
    SET @Iterator = 1

    DECLARE @FoundIndex INT
    SET @FoundIndex = CHARINDEX(@Delimeter,@RowData)
    declare @keyFoundIndex int
    set @keyFoundIndex=charindex(@Delimeter, @RowKey)


    WHILE (@FoundIndex>0)
    BEGIN
        INSERT INTO @RtnValue (keyValue, Data)
        SELECT KeyValue=LTRIM(RTRIM(SUBSTRING(@RowKey, 1, @keyFoundIndex - 1))),
            Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))


        SET @RowKey=substring(@RowKey, @keyFoundIndex + datalength(@Delimeter)/2, len(@RowKey))


        SET @RowData = SUBSTRING(@RowData,@FoundIndex + DATALENGTH(@Delimeter) / 2,LEN(@RowData))

        SET @Iterator = @Iterator + 1
        SET @FoundIndex = CHARINDEX(@Delimeter, @RowData)
        SET @keyFoundIndex = CHARINDEX(@Delimeter, @RowKey)
    END

    INSERT INTO @RtnValue (keyValue, Data)
    SELECT keyValue=ltrim(rtrim(@RowKey)), Data = LTRIM(RTRIM(@RowData))

    RETURN
END
于 2012-04-13T08:24:09.037 回答
0

如果您可以更改输入以便varchar遵循以下模式:

'key[0],value[1]:key[1],value[1]:...key[n]:value[n]'

那会让你varchar像这样:

'10,20:1,30'

然后给出这个拆分函数:

CREATE FUNCTION dbo.Split (@s varchar(512),@sep char(1))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
GO

您的 sql 查询非常简单。像这样:

DECLARE @varcharToSplit VARCHAR(512)
SET @varcharToSplit='10,20:1,30'
SELECT
    pvt.RowIndex,
    pvt.[1] AS [Key],
    pvt.[2] AS Value
FROM
(
    SELECT
        SplitColumns.pn AS ColumnIndex,
        SplitColumns.s AS ColumnValue,
        SplitRows.pn AS RowIndex
    FROM
        dbo.Split(@varcharToSplit,':') AS SplitRows
        CROSS APPLY dbo.Split(SplitRows.s,',') AS SplitColumns
) AS SourceTable
PIVOT
(
    MAX(ColumnValue)
    FOR ColumnIndex IN ([1],[2])
) AS pvt
于 2012-04-13T08:28:00.140 回答