SQL选择或插入返回ID
好的,这里有一个快速的SQL问题(使用SQL-server-2008) 我有一个映射表SQL选择或插入返回ID,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,好的,这里有一个快速的SQL问题(使用SQL-server-2008) 我有一个映射表names,包含以下列 IDDisplayName 我想做的是先 从[name]中选择[ID],其中[DisplayName]=“chuck” 但是,如果数据库中不存在名称“chuck”,我想创建它,并返回自动递增的ID 我想知道SQL是否有一些内置的方法可以轻松地实现这一点,或者我是否必须走很长的路 长途跋涉 SELECT COUNT(ID) AS count, ID FROM names WHERE Dis
names
,包含以下列
ID
DisplayName
我想做的是先
从[name]中选择[ID],其中[DisplayName]=“chuck”代码>
但是,如果数据库中不存在名称“chuck”,我想创建它,并返回自动递增的ID
我想知道SQL是否有一些内置的方法可以轻松地实现这一点,或者我是否必须走很长的路
长途跋涉
SELECT COUNT(ID) AS count, ID FROM names WHERE DisplayName='chuck'
IF(count > 0)
SELECT ID as ReturnID;
ELSE
BEGIN
INSERT INTO names(DisplayName) values('chuck');
SELECT scope_identity() as ReturnID;
END
我没有测试最后一句话,但我认为还有很长的路要走。如果没有内置的方式,如果有人能简单地纠正这句话,我将不胜感激(因为我确信它不是完全正确的)。我会:
IF (NOT EXISTS(SELECT null from names where DisplayName='Chuck'))
INSERT INTO Names (DisplayName) Values ('Chuck')
SELECT ID as ReturnID FROM Names where DisplayName='Chuck'
虽然节省不多,但您也应该注意事务:
set XACT_ABORT on
begin tran
declare @ID int
select @ID = ID from names with (holdlock, updlock) WHERE DisplayName='chuck'
if @@rowcount = 0
begin
INSERT INTO names(DisplayName) values('chuck');
set @ID = scope_identity();
end
select @ID as ReturnID;
commit tran
注意表提示的用法-holdlock和updlock。它们阻止另一个线程执行完全相同的查询并再次创建行。有关更多信息,请查看隔离、同步、死锁和并发更新
go
create table names
(
Id int primary key identity(1,1),
displayname varchar(100),
);
go
create procedure P1
@displayname varchar(100)
as
insert into names (displayname)
select @displayname
where not exists (
select * from names, (select @displayname as displayname) as names2
where names.displayname = names2.displayname);
-- race condition is possible here,
-- but in some cases you still may get away with this
select id from names where displayname = @displayname;
go
declare @dn varchar(100);
set @dn = 'chuck'; exec P1 @dn; exec P1 @dn; exec P1 @dn;
set @dn = 'buck'; exec P1 @dn; exec P1 @dn;
select * from names;
go
drop table names; drop procedure P1;
输出将1,1,1,2,2
,表格内容有两行大。如果只支持200*+,请使用您能提供一个示例吗?我正在努力学习使用sql的更高级的方法。@kelton52:在文章的末尾有一些例子OMG Ponies linked。你需要向下滚动一点。@zespri我看到了这些例子,但没有一个是我想做的。我通读了这些例子,但不理解它们。此外,如果他把他的评论作为一个例子的答案,我可以选择它。@kelton52这是最后一个使用OUTPUT
的例子,但这在你的例子中不起作用。它仅在存在插入或更新场景时有效。否则,当记录已经存在时,输出将是空的。好吧,运行这个,现在表已经死锁了…有什么想法吗?你也有两次这样的想法,假设不是有意的,sql也不会识别xac_ABORT基本上每次这个查询都会工作,但是对表的其他查询都不会工作。还要记住,此查询将从一个脚本运行,而不是从一个网站或任何东西运行…因此不会同时有多个查询调用..本质上,它只是一个将CSV值插入数据库的perl脚本,这不是最多执行2个查询,最糟糕的是执行1个查询吗?