从 C# 中的插入查询返回 ID
Posted
技术标签:
【中文标题】从 C# 中的插入查询返回 ID【英文标题】:Returning ID from insert query in C# 【发布时间】:2012-04-26 05:33:28 【问题描述】:我有一个问题,当使用 C# 和 MS Access 数据库将记录插入表中时,如何返回表的自动递增 id。以下是我尝试过的代码。
string data1 = string.Format("insert into Enquiry(fname,mname,lname,date_of_enq,address,contact_no,email_id,course_id,other,probable_date,updated_date,status)values('0','1','2','3','4','5','6','7','8','9','10','11')",
txtfName.Text, txtmName.Text, txtlName.Text, fullDate.Text, txtaddress.Text, txtContactNo.Text, varemail, CBCourse.SelectedValue.ToString(), txtOther.Text, DTPFeedBackDate.Text, updated_date, status);
我想要在表中自动递增的插入记录的 id。我怎样才能得到它?
【问题讨论】:
关心对 sql-injection 做些什么? 你的 dbms 是什么? mssql, mysql, ...?? 【参考方案1】:只需将 SELECT @@IDENTITY
添加到您的查询中,并将其作为标量执行(请注意,还有其他方法,具体取决于您的身份范围)
这适用于 mssql - 对于其他系统,我正在等待您对我的评论的回答!
顺便说一句:我不会以这种方式执行查询 - 关键字是 sql-injection。而是去参数!
【讨论】:
thanx... 但我不知道如何将其添加到插入查询string data1 = string.Format("insert into Enquiry(fname,mname,lname,date_of_enq,address,contact_no,email_id,course_id,other,probable_date,updated_date,status)values('0','1','2','3','4','5','6','7','8','9','10','11'); SELECT @@IDENTITY", txtfName.Text, txtmName.Text, txtlName.Text, fullDate.Text, txtaddress.Text, txtContactNo.Text, varemail, CBCourse.SelectedValue.ToString(), txtOther.Text, DTPFeedBackDate.Text, updated_date, status);
- 没那么难吧?【参考方案2】:
您可以使用以下内容:
Select Ident_Current(TableName);
SELECT @@IDENTITY;
SELECT SCOPE_IDENTITY();
选择@@IDENTITY 它返回在连接上生成的最后一个 IDENTITY 值,与生成该值的表无关,也与生成该值的语句的范围无关。 @@IDENTITY 将返回在当前会话中输入到表中的最后一个标识值。虽然@@IDENTITY 仅限于当前会话,但它不限于当前范围。如果您在一个表上有一个触发器导致在另一个表中创建一个身份,您将获得最后创建的身份,即使它是创建它的触发器。
选择 SCOPE_IDENTITY() 它返回连接上和同一范围内的语句生成的最后一个 IDENTITY 值,而不管生成该值的表是什么。 SCOPE_IDENTITY() 与@@IDENTITY 一样,将返回在当前会话中创建的最后一个身份值,但它也会将其限制在您当前的范围内。换句话说,它将返回您显式创建的最后一个标识值,而不是由触发器或用户定义的函数创建的任何标识。
SELECT IDENT_CURRENT(‘表名’) 它返回表中生成的最后一个 IDENTITY 值,与创建该值的连接无关,也与生成该值的语句的范围无关。 IDENT_CURRENT 不受范围和会话限制;它仅限于指定的表。 IDENT_CURRENT 返回为任何会话和任何范围内的特定表生成的标识值。
为避免与稍后添加触发器相关的潜在问题,请始终使用 SCOPE_IDENTITY() 来返回 T SQL 语句或存储过程中最近添加的行的标识。
在 MsAccess 中
// Include a variable and a command to retrieve the identity value from the Access database.
int newID = 0;
OleDbCommand idCMD = new OleDbCommand("SELECT @@IDENTITY", nwindConn);
// Retrieve the identity value and store it in the CategoryID column.
newID = (int)idCMD.ExecuteScalar();
return newID;
【讨论】:
To avoid the potential problems associated with adding a trigger later on, always use SCOPE_IDENTITY() to return the identity of the recently added row in your T SQL Statement or Stored Procedure.
... 好吧 ... aaaannnd,因为SELECT IDENT_CURRENT('table');
没有绑定到连接,如果与第二个stmt一起使用,它绝不会在并发系统中正常工作(这是这个解决方案的好处)
所有这三套西装在不同的问题领域,所以参考链接并选择更适合你的。谢谢安德烈亚斯。
我相信,您应该在回答中提供一些相关信息 - 或者至少指出,每个解决方案都有特定的域...引用/指向外部文章,其中需要额外的大脑来检测这样一个事实,即每个解决方案都有自己的域,这有点有害 :) 并且,如果您认为您必须点击链接(做出 正确 选择 -取决于您的设置),为什么还要包含// Best way
- 这与您的信念背道而驰,而且绝不会受到影响,因此是无益的评论!
它给出了错误未定义的函数@@IDENTITY。我使用了以下代码。 string idd1 = string.Format("SELECT @@IDENTITY");
将 SELECT @@IDENTITY 与 ExecuteScalar 一起使用。这是一条sql语句。【参考方案3】:
这个 C# 代码使用 Oracle.ManagedDataAccess 4.121.1.0 库为我工作:
OracleConnection conn = oracleConnLicen();
OracleCommand cmd = conn.CreateCommand();
conn.Open();
cmd.CommandText = "INSERT INTO account (name) VALUES ('Adam') RETURNING id INTO :p_id";
然后在 ExecuteNonQuery 之前:
OracleParameter pId = new OracleParameter("p_id", OracleDbType.Int32)
Direction = ParameterDirection.Output
;
cmd.Parameters.Add(pId);
cmd.ExecuteNonQuery();
return Convert.ToInt32(pId.Value.ToString());
【讨论】:
以上是关于从 C# 中的插入查询返回 ID的主要内容,如果未能解决你的问题,请参考以下文章
从 c# 查询 MySQL 返回 System.Byte[]