在系统中经常会遇到向数据库中批量插入数据情况,存储过程中没有数组,只有通过字符串分割循环插入,下面是一个本人研究的一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
create
proc [dbo].[Proc_TestBatchMainDetailIns]
@mainName nvarchar(50),@detailNameStr nvarchar(
max
),@detailAgeStr nvarchar(
max
),
@detailRowCount
int
=1,@tmpFlag
int
=1,@newMainId
int
=0
as
begin
insert
into
TestProBatch_Main(MainName)
values
(@mainName)
select
@newMainId=@@IDENTITY
set
@detailRowCount=len(@detailNameStr)-len(
replace
(@detailNameStr,
'|'
,
''
))+1
set
@detailNameStr=@detailNameStr+
'|'
set
@detailAgeStr=@detailAgeStr+
'|'
while(@tmpFlag<=@detailRowCount)
begin
insert
into
TestProcBatch_Detail(MainId,DetailName,DetailAge)
values
(@newMainId,dbo.F_RtnStrBySplitIndex(@detailNameStr,@tmpFlag),dbo.F_RtnStrBySplitIndex(@detailAgeStr,@tmpFlag))
set
@tmpFlag=@tmpFlag+1
end
end
|
这个例子是插入一条主单信息和对应的多条子信息,下面是两张表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
--主表
CREATE
TABLE
[dbo].[TestProBatch_Main](
[ID] [
int
] IDENTITY(1,1)
NOT
NULL
primary
key
,
[MainName] [nvarchar](50)
NOT
NULL
,
[CreateTime] [datetime]
NOT
NULL
);
--子表
CREATE
TABLE
[dbo].[TestProcBatch_Detail](
[ID] [
int
] IDENTITY(1,1)
NOT
NULL
primary
key
,
[MainId] [
int
]
NOT
NULL
,
[DetailName] [nvarchar](50)
NOT
NULL
,
[DetailAge] [
int
]
NOT
NULL
,
[CreateTime] [datetime]
NOT
NULL
);
|
dbo.F_RtnStrBySplitIndex是自定义的标量值函数,用于返回第几个分割符对应的字符串,如dbo.F_RtnStrBySplitIndex('jack|lilei|tom|nike',3) 则返回tom
下面是函数的创建
1
2
3
4
5
6
7
8
9
10
11
12
|
create
function
[dbo].[F_RtnStrBySplitIndex](@procStr nvarchar(
max
),@splitStrIdx
int
)
returns
nvarchar(250)
as
begin
declare
@rtnStr nvarchar(250)
declare
@currentSplitIdx
int
declare
@preSplitIdx
int
set
@currentSplitIdx=dbo.F_RtnSomeCharIdxInStrByNo(
'|'
,@procStr,@splitStrIdx)
set
@preSplitIdx=dbo.F_RtnSomeCharIdxInStrByNo(
'|'
,@procStr,@splitStrIdx-1)
set
@rtnStr=
SUBSTRING
(@procStr,@preSplitIdx+1,@currentSplitIdx-@preSplitIdx-1)
return
@rtnStr
end
|
这个函数当中又用到了另一个函数dbo.F_RtnSomeCharIdxInStrByNo,用于返回某个字符在一个字符串的位置,下面是该函数的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
ALTER
function
[dbo].[F_RtnSomeCharIdxInStrByNo](@findSplitStr
varchar
(250), @procStr
varchar
(8000), @n
smallint
)
returns
int
as
begin
if @n < 1
return
(0)
declare
@start
smallint
, @
count
smallint
, @
index
smallint
, @len
smallint
set
@
index
= charindex(@findSplitStr, @procStr)
if @
index
= 0
return
(0)
else
select
@
count
= 1, @len = len(@findSplitStr)
while @
index
> 0
and
@
count
< @n
begin
set
@start = @
index
+ @len
select
@
index
= charindex(@findSplitStr, @procStr, @start), @
count
= @
count
+ 1
end
if @
count
< @n
set
@
index
= 0
return
(@
index
)
end
|
调用存储过程:exec Proc_TestBatchMainDetailIns 'mainName1','jack|lilei|tom|nike','20|18|22|17'
下面是成功插入后查询到的结果: