如果我是你,我会创建一个简单的函数,用 ';' 分隔值 像这样:
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;
将返回:
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