从 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[]

我想从 C# 中的选择查询中获取 id 但每次我运行程序时,查询都会返回“-1” [重复]

c#如何返回插入行的ID值

如何在sql中插入记录时返回id(id为自动增长)

sql插入行,但从该行返回一个项目

从数据库获取值后,C# 中的查询返回 false