use*_*925 26 sql t-sql sql-server sql-server-2008
我的存储过程接收一个逗号分隔的字符串参数:
DECLARE @Account AS VARCHAR(200)
SET @Account = 'SA,A'
Run Code Online (Sandbox Code Playgroud)
我需要从中做出这样的声明:
WHERE Account IN ('SA', 'A')
Run Code Online (Sandbox Code Playgroud)
这样做的最佳做法是什么?
t-c*_*.dk 31
创建此功能(sqlserver 2005+)
CREATE function [dbo].[f_split]
(
@param nvarchar(max),
@delimiter char(1)
)
returns @t table (val nvarchar(max), seq int)
as
begin
set @param += @delimiter
;with a as
(
select cast(1 as bigint) f, charindex(@delimiter, @param) t, 1 seq
union all
select t + 1, charindex(@delimiter, @param, t + 1), seq + 1
from a
where charindex(@delimiter, @param, t + 1) > 0
)
insert @t
select substring(@param, f, t - f), seq from a
option (maxrecursion 0)
return
end
Run Code Online (Sandbox Code Playgroud)
使用此声明
SELECT *
FROM yourtable
WHERE account in (SELECT val FROM dbo.f_split(@account, ','))
Run Code Online (Sandbox Code Playgroud)
将我的split函数与XML split进行比较:
测试数据:
select top 100000 cast(a.number as varchar(10))+','+a.type +','+ cast(a.status as varchar(9))+','+cast(b.number as varchar(10))+','+b.type +','+ cast(b.status as varchar(9)) txt into a
from master..spt_values a cross join master..spt_values b
Run Code Online (Sandbox Code Playgroud)
XML:
SELECT count(t.c.value('.', 'VARCHAR(20)'))
FROM (
SELECT top 100000 x = CAST('<t>' +
REPLACE(txt, ',', '</t><t>') + '</t>' AS XML)
from a
) a
CROSS APPLY x.nodes('/t') t(c)
Elapsed time: 1:21 seconds
Run Code Online (Sandbox Code Playgroud)
f_split:
select count(*) from a cross apply clausens_base.dbo.f_split(a.txt, ',')
Elapsed time: 43 seconds
Run Code Online (Sandbox Code Playgroud)
这将从一次运行变为运行,但你明白了