如果我是你,我会创建一个简单的函数,用分号分隔数值,像这样:
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'fn_Split_List') AND xtype IN (N'FN', N'IF', N'TF'))
BEGIN
DROP FUNCTION [dbo].[fn_Split_List]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_Split_List](@List NVARCHAR(512))
RETURNS @ResultRowset TABLE ( [Value] NVARCHAR(128) PRIMARY KEY)
AS
BEGIN
DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@List, ';', ']]></r><r><![CDATA[') + ']]></r>'
INSERT INTO @ResultRowset ([Value])
SELECT DISTINCT RTRIM(LTRIM(Tbl.Col.value('.', 'NVARCHAR(128)')))
FROM @xml.nodes('//r') Tbl(Col)
RETURN
END
GO
那么就简单地这样称呼它:
SET NOCOUNT ON
GO
DECLARE @RawData TABLE( [Value] NVARCHAR(256))
INSERT INTO @RawData ([Value] )
VALUES ('1111111;22222222')
,('3333333;113113131')
,('776767676')
,('89332131;313131312;54545353')
SELECT SL.[Value]
FROM @RawData AS RD
CROSS APPLY [fn_Split_List] ([Value]) as SL
SET NOCOUNT OFF
GO
结果如下:
Value
1111111
22222222
113113131
3333333
776767676
313131312
54545353
89332131
无论如何,该函数中的逻辑并不复杂,因此您可以轻松地将其放置在任何需要的位置。
注意:使用“;”分隔的值数量没有限制,但是函数中有长度限制,如果需要,可以将其设置为NVARCHAR(MAX)。
编辑:
从我所看到的情况来看,您示例中的某些行会导致函数返回空字符串。例如:
number;number;
will return:
number
number
'' (empty string)
为了清除它们,只需像这样在上述语句中添加以下where子句:
SELECT SL.[Value]
FROM @RawData AS RD
CROSS APPLY [fn_Split_List] ([Value]) as SL
WHERE LEN(SL.[Value]) > 0