我想要一个TSQL表值函数,它可以执行嵌套解析并将结果返回到两列表中。
示例:
从udf_nested_split中选择*('a - > 1,b - > 16,x - > 99')
会产生:
Tag|Value
a|1
b|16
x|99
答案 0 :(得分:3)
这是一个强力函数,但它有效...需要两个参数(一个用于主分隔符,一个用于辅助分隔符):
IF EXISTS ( SELECT * from dbo.sysobjects WHERE id = object_id(N'[dbo].[doubleSplit]')
AND OBJECTPROPERTY(id, N'IsTableFunction') = 1 )
DROP FUNCTION [dbo].[doubleSplit]
GO
CREATE FUNCTION dbo.doubleSplit (
@sourceString varchar(MAX),
@primaryDelimiter varchar(100),
@secondaryDelimiter varchar(100) )
RETURNS @tblArray TABLE
(
ElementID smallint IDENTITY(1,1),
Element varchar(MAX),
Value varchar(MAX)
)
AS
BEGIN
DECLARE @primaryIndex smallint
DECLARE @secondaryIndex smallint
DECLARE @primaryStart smallint
DECLARE @secondaryStart smallint
DECLARE @primaryDelimiterSize smallint
DECLARE @seondaryDelimiterSize smallint
DECLARE @primaryElement varchar(MAX);
DECLARE @seondaryElement varchar(MAX);
SET @primaryDelimiterSize = LEN(@primaryDelimiter)
SET @seondaryDelimiterSize = LEN(@secondaryDelimiter)
--loop through source string and add elements to destination table array
WHILE LEN(@sourceString) > 0
BEGIN
SET @primaryIndex = CHARINDEX(@primaryDelimiter, @sourceString)
IF @primaryIndex = 0
BEGIN
SET @secondaryIndex = CHARINDEX(@secondaryDelimiter, @sourceString)
IF @secondaryIndex = 0
BEGIN
INSERT INTO @tblArray (Element, Value) VALUES(@sourceString, '')
END
ELSE
BEGIN
SET @secondaryStart = @secondaryIndex + @seondaryDelimiterSize;
INSERT INTO @tblArray (Element, Value)
VALUES(SUBSTRING(@sourceString, 1, @secondaryIndex - 1),
SUBSTRING(@sourceString, @secondaryIndex + @seondaryDelimiterSize, LEN(@sourceString) - @secondaryStart + 1))
END
BREAK
END
ELSE
BEGIN
SELECT @primaryElement = SUBSTRING(@sourceString, 1, @primaryIndex - 1);
SET @secondaryIndex = CHARINDEX(@secondaryDelimiter, @primaryElement)
SET @secondaryStart = @secondaryIndex + @seondaryDelimiterSize;
INSERT INTO @tblArray (Element, Value)
VALUES(SUBSTRING(@primaryElement, 1, @secondaryIndex - 1),
SUBSTRING(@primaryElement, @secondaryIndex + @seondaryDelimiterSize, LEN(@primaryElement) - @secondaryStart + 1))
SET @primaryStart = @primaryIndex + @primaryDelimiterSize
SET @sourceString = SUBSTRING(@sourceString, @primaryStart , LEN(@sourceString) - @primaryStart + 1)
END
END
RETURN
END
GO
然后您可以这样调用它并获得预期结果:
SELECT * FROM dbo.doubleSplit('a-->1,b-->16,x-->99', ',', '-->')
返回:
ElementID Element Value
1 a 1
2 b 16
3 x 99
而且:
SELECT * FROM dbo.doubleSplit('a-->1', ',', '-->')
返回:
ElementID Element Value
1 a 1
等等。