可以考虑用函数来拆分:if exists(select * from sys.objects where name = 'f_splitSTR' and type = 'tf')
drop function dbo.f_splitSTR
gocreate function dbo.f_splitSTR
(
@s varchar(8000), --要分拆的字符串
@split varchar(10) --分隔字符
)
returns @re table( --要返回的临时表
col varchar(1000) --临时表中的列
)
as
begin
declare @len int
set @len = LEN(@split) --分隔符不一定就是一个字符,可能是2个字符
while CHARINDEX(@split,@s) >0
begin
insert into @re
values(left(@s,charindex(@split,@s) - 1))
set @s = STUFF(@s,1,charindex(@split,@s) - 1 + @len ,'') --覆盖:字符串以及分隔符
end
insert into @re values(@s)
return --返回临时表
end
go
--效果
select c.col
from dbo.f_splitSTR('a,b,c,d',',') c
/*
col
a
b
c
d
*/
drop table test
go
create table test
(
id int,
name varchar(10),
[key] varchar(20)
)
go
insert test
select 1,'lisa','li,is,sa' union all
select 2,'sophia','ab,cd,ef' union all
select 3,'lori','12,34,23'
go
select
id,
a.name,
SUBSTRING([key],number,CHARINDEX(',',[key]+',',number)-number) as [key]
from
test a,master..spt_values
where
number >=1 and number<=len([key])
and type='p'
and substring(','+[key],number,1)=','
/*
id name key
-----------------------------
1 lisa li
1 lisa is
1 lisa sa
2 sophia ab
2 sophia cd
2 sophia ef
3 lori 12
3 lori 34
3 lori 23
*/
比如说“15874,154874,15474,15474,1547,154748,1584847……”里面有2000个“xxx,”。然后insert到数据里面的A表中的字段spnum,A表的另外一个字段ct插入“内容”。
写SQL的话,就是insert into A(spnum,ct)value(xxx,'内容')。这样写就每一次都连接一次数据库。速度很慢。
怎么优化这个写法
CREATE TABLE test (NAME VARCHAR(max))
INSERT INTO test VALUES('15874,154874,15474,15474,1547,154748,1584847')
go
select
SUBSTRING(a.NAME,number,CHARINDEX(',',a.NAME+',',number)-number) as spnum,'内容' ct
from
test a,master..spt_values
where
number >=1 and number<=len(a.NAME)
and type='p'
and substring(','+a.NAME,number,1)=',' /*
spnum ct
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----
15874 内容
154874 内容
15474 内容
15474 内容
1547 内容
154748 内容
1584847 内容 */
select
SUBSTRING(a.NAME,number,CHARINDEX(',',a.NAME+',',number)-number) as spnum,'内容' ct
from
test a,master..spt_values
where
number >=1 and number<=len(a.NAME)
and type='p'
and substring(','+a.NAME,number,1)=','
if exists(select * from sys.objects where name = 'f_splitSTR' and type = 'tf')
drop function dbo.f_splitSTR
go
create function dbo.f_splitSTR
(
@s varchar(8000), --要分拆的字符串
@split varchar(10) --分隔字符
)
returns @re table( --要返回的临时表
col varchar(1000) --临时表中的列
)
as
begin
declare @len int
set @len = LEN(@split) --分隔符不一定就是一个字符,可能是2个字符
while CHARINDEX(@split,@s) >0
begin
insert into @re
values(left(@s,charindex(@split,@s) - 1))
set @s = STUFF(@s,1,charindex(@split,@s) - 1 + @len ,'') --覆盖:字符串以及分隔符
end
insert into @re values(@s)
return --返回临时表
end
go
--效果
insert into 你的表(列)
select c.col
from dbo.f_splitSTR('15874,154874,15474,15474,1547,154748,1584847',',') c
/*
col
a
b
c
d
*/
你觉得与系统表连表后这样的集合式插入会快么?个人建议老老实在在前端代码里拼出insert语句, 或者插入到datatable类似于这样的容器里,然后bulkcopy\bulkinsert或者其它的方案bcp等等