获取新增数据的唯一标识
在项目开发过程中我们常会遇到这样的情况:往数据库中插入了一条新数据后,需要知道这条新数据的唯一标识,比如ID
1.Oracle
string sqlStr = String.Format(" insert into TableName(id,A,B) values('{0}','{1}','{2}') ", id, a, b);
//。。。。。。
myCmd.ExecuteNonQuery();
对于oracle直接读取相应的序列就可以了,我之前还以为会产生冲突,后来才发现是自己对序列的机制不太了解。
值得注意的是:不管新数据插入成功与否,得到的都是这次操作准备插入的ID值,所以获取值之前最好判断一下插入成功了没有。
2.SQL Server
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');