2012-04-13 61 views
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', ',') 

結果是:


這是真的

當我使用此功能:

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

結果是:


11,20

2 empthy 30

它是假的

如何修復存儲過程中的第二次調用?

回答

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 
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 
+0

thans的想法,我會用它來...... – loviji 2012-04-13 11:14:09