2015-06-12 30 views
1

我正在创建一个分割字符串的函数。我想将该函数传递给一个字符串并返回几行(根据字符串的长度,行的数量将是动态的)。返回多列的函数

我想可能使用表函数并将其加入到我的查询中。

我是不是要求这是为我写的,我只是想知道这是否甚至可能在SQL Server 2014中,以及如果是这样,最好的方法是什么。

因此字符串 'ABC' 将作为返回:

COL1 COL2 COL3 
A  B C 
+0

是 - 它被称为[表值函数](https://technet.microsoft.com/en-us/library/ms191165(v = sql.105).aspx)。 –

+0

是的,这是我一直在看,我在上面提到它。它可以用于分割一个字符串,并动态地在一个单独的列中返回每个字符? –

+0

否 - 列必须是静态的。但是,您可以返回多个_rows_,请参阅我的答案。 –

回答

2

我只是想知道,这是在SQL Server甚至有可能2014

是的,你可以创建table-valued user defined functions说返回,以及表值。

因此字符串“ABC”将返回:

COL1 COL2 COL3 
A  B C 

好了,现在你就麻烦了 - 表值函数必须有一个预先定义的返回值架构,所以你不能动态设置列名称。你可以返回这些作为,虽然:

Item Value 
1  A 
2  B 
3  C 
+0

也许返回为行然后应用一个动态的关键点可以得到我以后的结果。这将是可怕的... –

+0

是的动态枢轴也没有乐趣。 –

+0

@DStanley动态SQL是乐趣开始的地方...... –

1

你没有提到你在哪里要应用这一点,但也有解决方案:

DECLARE @t TABLE(id int, n VARCHAR(50)) 
INSERT INTO @t VALUES 
(1, 'ABCDEF'), 
(2, 'EFGHIJKLMNOPQ') 


;WITH cte AS 
(SELECT id, n, SUBSTRING(n, 1, 1) c, 1 AS ind FROM @t 
UNION ALL 
SELECT id, n, SUBSTRING(n, ind + 1, 1), ind + 1 FROM cte WHERE LEN(n) > ind 
) 

SELECT * 
FROM cte 
PIVOT (MAX(c) FOR ind IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[12],[13],[14],[15])) p 

输出:

id n    1 2 3 4 5 6 7 8 9 10 12 13 14 15 
1 ABCDEF   A B C D E F NULL NULL NULL NULL NULL NULL NULL NULL 
2 EFGHIJKLMNOPQ E F G H I J K L M N P Q NULL NULL 

这里是动态版本:

DECLARE @l INT, @c VARCHAR(MAX) = '' 
SELECT @l = MAX(LEN(n)) FROM PivotTable 

WHILE @l > 0 
BEGIN 
SET @c = ',[' + CAST(@l AS VARCHAR(MAX)) + ']' + @c 
SET @l = @l - 1 
END 

SET @c = STUFF(@c, 1, 1,'') 

DECLARE @s NVARCHAR(MAX) = ' 
;WITH cte AS 
(SELECT id, n, SUBSTRING(n, 1, 1) c, 1 AS ind FROM PivotTable 
UNION ALL 
SELECT id, n, SUBSTRING(n, ind + 1, 1), ind + 1 FROM cte WHERE LEN(n) > ind 
) 

SELECT * 
FROM cte 
PIVOT (MAX(c) FOR ind IN(' + @c + ')) p' 

EXEC (@s)