您需要一种方法来拆分和处理 TSQL 中的字符串,有很多方法可以做到这一点。本文涵盖了几乎所有方法的优点和缺点:
SQL Server 2000 及更早版本中的数组和列表
您需要创建一个拆分功能。这是如何使用拆分功能的:
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
[我更喜欢数字表方法在 TSQL 中拆分字符串](SQL Server 2000 及更早版本中的数组和列表)但是在 SQL Server 中拆分字符串的方法有很多,请参阅上一个链接,其中解释了每种方法的优缺点.
要使 Numbers Table 方法起作用,您需要执行此一次时间表设置,这将创建一个Numbers
包含 1 到 10,000 行的表:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
设置 Numbers 表后,创建此拆分函数:
CREATE FUNCTION inline_split_me (@SplitOn char(1),@param varchar(7998)) RETURNS TABLE AS
RETURN(SELECT substring(@SplitOn + @param + ',', Number + 1,
charindex(@SplitOn, @SplitOn + @param + @SplitOn, Number + 1) - Number - 1)
AS Value
FROM Numbers
WHERE Number <= len(@SplitOn + @param + @SplitOn) - 1
AND substring(@SplitOn + @param + @SplitOn, Number, 1) = @SplitOn)
GO
您现在可以轻松地将 CSV 字符串拆分为表格并加入表格:
select * from dbo.inline_split_me(';','1;22;333;4444;;') where LEN(Value)>0
输出:
Value
----------------------
1
22
333
4444
(4 row(s) affected)
让你的新表使用这个:
--set up tables:
create table TableA (id int, commodities varchar(8000))
INSERT TableA VALUES (1135,'fish,eggs,meat')
INSERT TableA VALUES (1127,'flour,oil')
Create table TableB (id int, commodities varchar(8000))
--populate TableB
INSERT TableB
(id, commodities)
SELECT
a.id,c.value
FROM TableA a
CROSS APPLY dbo.inline_split_me(',',a.commodities) c
--show tableB contents:
select * from TableB
输出:
id commodities
----------- -------------
1135 fish
1135 eggs
1135 meat
1127 flour
1127 oil
(5 row(s) affected)
在 Conrad Frix 关于 SQL Server 2000 不支持的评论后编辑CROSS APPLY
这将做同样的事情:
INSERT TableB
(id, commodities)
SELECT
a.id,NullIf(SubString(',' + a.commodities + ',' , number , CharIndex(',' , ',' + a.commodities + ',' , number) - number) , '')
FROM TableA a
INNER JOIN Numbers n ON 1=1
WHERE SubString(',' + a.commodities + ',' , number - 1, 1) = ','
AND CharIndex(',' , ',' + a.commodities + ',' , number) - number > 0
AND number <= Len(',' + a.commodities + ',')
并且基于@Rup 答案中链接中的代码。它基本上删除了函数调用并在主查询中进行拆分(使用类似的 Numbers 表拆分),因此不需要CROSS APPLY
.