【发布时间】:2014-12-01 23:42:12
【问题描述】:
我从一个使用 sql 数据库的现有程序开始,并尝试对其进行修改,以便它使用批量插入(而不是一个接一个)并防止重复条目。
这是我添加一个用户的功能(只要该用户不存在),它应该可以工作:
use [DebugDatabase]
go
set ansi_nulls on
go
set quoted_identifier on
go
create procedure [dbo].[AddUser]
@Id bigint, @Login nvarchar(100), @ConsoleName nvarchar(100), @Ip nvarchar(50)
as
begin
set nocount on;
declare @FoundId bigint = (select Id from [User] where Id = @Id)
if @FoundId is null
begin
insert into [User] (Id, Login, ConsoleName, Ip) values (@Id, @Login, @ConsoleName, @Ip)
end
else
begin
update [User]
set [Id] = @Id,
[Login] = @Login,
[ConsoleName] = @ConsoleName,
[Ip] = @Ip
where Id = @Id
end
select top 1 * from [User] where Id = @Id;
end
go
现在我想为批量插入编写一个函数,它调用上述函数来检查每个条目。显示我的方式,这需要自定义表格类型:
use [DebugDatabase]
go
create type [dbo].[UserTableType] as table
(
[Id] [bigint] not null,
[Login] [nvarchar](100) not null default 'Unknown',
[ConsoleName] [nvarchar](100) not null default 'Unknown',
[Ip] [nvarchar](50) not null default '0.0.0.0'
)
go
以及添加多个条目的功能(这是我遇到的问题):
use [DebugDatabase]
go
set ansi_nulls on
go
set quoted_identifier on
go
create procedure [AddMultipleUsers]
@users UserTableType readonly
as
declare
@Id bigint,
@Login nvarchar(100),
@ConsoleName nvarchar(100),
@Ip nvarchar(50)
begin
insert into @Id select Id from @users
insert into @Login select Login from @users
insert into @ConsoleName select ConsoleName from @users
insert into @Ip select Ip from @users
exec AddUser @Id, @Login, @ConsoleName, @Ip
end
go
我得到“必须声明表变量“@Id”。我不确定如何从表类型中提取单个值以便将它们传递给 AddUser 函数。我真的很喜欢,虽然,是一种在一个函数调用中完成所有操作的方法,但我还没有遇到过这样的事情。
【问题讨论】:
-
您对“@Id”的插入将不起作用,因为“@Id”是一个 bigint 而不是一个表。您应该像这样设置@Id 参数:'Set @Id= (Select top 1 Id from @users)'
标签: sql stored-procedures bulkinsert