获取新增数据的唯一标识

在项目开发过程中我们常会遇到这样的情况:往数据库中插入了一条新数据后,需要知道这条新数据的唯一标识,比如ID 

1.Oracle

int id = MyDB.ExecSql("select TableName_seq.nextval from dual");  //表TableName的序列TableName_seq
string sqlStr = String.Format(" insert into TableName(id,A,B) values('{0}','{1}','{2}') ", id, a, b);
//。。。。。。
myCmd.ExecuteNonQuery();

对于oracle直接读取相应的序列就可以了,我之前还以为会产生冲突,后来才发现是自己对序列的机制不太了解。
值得注意的是:不管新数据插入成功与否,得到的都是这次操作准备插入的ID值,所以获取值之前最好判断一下插入成功了没有。

 

2.SQL Server

SqlConnection myConn = new SqlConnection();
myConn.ConnectionString 
= connStr;
myConn.Open();

SqlCommand myCmd 
= myConn.CreateCommand();
string sqlStr = String.Format("insert into table(A,B) values('{0}','{1}');", a, b);
sqlStr 
+= "select  SCOPE_IDENTITY();";

string newID = "";
try
{
     SqlTransaction myTran 
= myConn.BeginTransaction();
     myCmd.Transaction 
= myTran;
     myCmd.CommandText 
= sqlStr;
     newID 
= myCmd.ExecuteScalar().ToString();
     myTran.Commit();
}
catch (Exception ex)
{
     myTran.Rollback();
}

这里面主要用到了事务和IDENT_CURRENT,IDENT_CURRENT 类似于 SQL Server 2000 标识函数 SCOPE_IDENTITY
和 @@IDENTITY。这三个函数都返回最后生成的标识值。但是,上述每个函数中定义的“最后”的作用域和会话有所不同。 

 ▪ IDENT_CURRENT         返回为任何会话和任何作用域中的特定表最后生成的标识值。
 ▪ @@IDENTITY              返回为当前会话的所有作用域中的任何表最后生成的标识值。
 ▪ SCOPE_IDENTITY        返回为当前会话和当前作用域中的任何表最后生成的标识值。
 

例如,有两个表 Table1 和 Table2,在 Table1 上定义了一个 INSERT 触发器。当将某行插入 Table1 时,触发器被激发,
并在 Table2 中插入一行。这里有两个作用域:一个是在 Table1 上的插入,另一个是作为由于触发器的结果原因在 Table2
上的插入。如果我们不考虑多会话的情况,在Table1中插入一条数据,那么: 

select SCOPE_IDENTITY();             --返回插入Table1 中的 IDENTITY 值
select @@IDENTITY ;                    --返回插入Table2 中的 IDENTITY 值
select IDENT_CURRENT ('Table1');  -- 返回Table1 最后生成的 IDENTITY 值
select IDENT_CURRENT ('Table2');  -- 返回Table2 最后生成的 IDENTITY 值

 

PS:在 SQL Server2005 中有更简单的方法:   insert into TableName(A,B) output inserted.id values('a','b');

 

posted @ 2008-11-20 15:59  baiyicug  阅读(894)  评论(5编辑  收藏  举报