在控制器中为 INSERT 获取标识值(执行插入命令并在 Sql 中返回插入的 Id)

Posted

技术标签:

【中文标题】在控制器中为 INSERT 获取标识值(执行插入命令并在 Sql 中返回插入的 Id)【英文标题】:Get an identity value in a controller for INSERT (Execute Insert command and return inserted Id in Sql) 【发布时间】:2021-04-27 14:32:40 【问题描述】:

目前,我正在使用 MVC 创建项目。现在我想在 INSERT 语句中插入一个身份 ID 值。

在我的控制器中:

string payment = @"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) 
                         VALUES('0','1',2)";
        int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
        if (pay == 1)
        
            string pid = "SELECT TOP 1 Payment_id FROM Payment ORDER BY Payment_id DESC";
            int paymentid = DBUtl.ExecSQL(pid);
        if (cart.Count() != 0)
        
            string order = @"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id) 
                     VALUES('0','1',2,3)";

现在,我想要已经插入到payment 表中的payment_id,这是第一条语句,并检索payment_id 并将其用于Order 表的INSERT 语句中

我怎样才能做到这一点?

请帮忙

谢谢

【问题讨论】:

SQL Injection alert - 您应该将您的 SQL 语句连接在一起 - 使用 参数化查询 来避免 SQL 注入 - 查看Little Bobby Tables 【参考方案1】:

其实DBUtil的代码包括:

public static int ExecSQL(string sql, params object[] list)

    List<String> escParams = new List<String>();

    foreach (object o in list)
    
        if (o == null)
            escParams.Add("");
        else
            escParams.Add(EscQuote(o.ToString()));
    

    DB_SQL = String.Format(sql, escParams.ToArray());

    int rowsAffected = 0;

    using (SqlConnection dbConn = new SqlConnection(DB_CONNECTION))
    using (SqlCommand dbCmd = dbConn.CreateCommand())
    
         try
         
              dbConn.Open();
              dbCmd.CommandText = DB_SQL;
              rowsAffected = dbCmd.ExecuteNonQuery();
         
         catch (System.Exception ex)
         
              DB_Message = ex.Message;
              rowsAffected = -1;
         
     

     return rowsAffected;

如您所知,ExecuteNonQuery 表示影响行的数字

所以,你可以如下图所示:

适用于 SQL SERVER 2005 及更高版本

   using (SqlConnection con=new SqlConnection(@"Your connectionString"))
    
        using(SqlCommand cmd=new SqlCommand("INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) output INSERTED.Payment_id VALUES(@Payment_Method,@Currency_Type,@Total_Amount)",con))
        
            cmd.Parameters.AddWithValue("@Payment_Method", "Cash");
            cmd.Parameters.AddWithValue("@Currency_Type", currency);
            cmd.Parameters.AddWithValue("@Total_Amount", total);
            con.Open();
        
            int payment_id =Convert.ToInt32(cmd.ExecuteScalar());
        
            if (con.State == System.Data.ConnectionState.Open) 
                con.Close();
        
            return payment_id ;
        

另外,您可以将查询更改为:

"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) VALUES(@Payment_Method,@Currency_Type,@Total_Amount)"; SELECT SCOPE_IDENTITY()" 

【讨论】:

嗨,Hesam,我试过你的方法,但仍然没有显示 payment_id 确保它有效,因为我已经对其进行了测试,正如您在此链接 (forums.asp.net/t/…) 上看到的那样,(ASP.NET 论坛)它使用 SELECT SCOPE_IDENTITY()OUTPUT INSERTED.ID这个情况。您也可以访问此链接docs.microsoft.com/en-us/sql/t-sql/functions/… (docs.microsoft.com) 插入完成了吗?它返回什么值? 返回payment_id显示错误。错误是“无法将类型'int'隐式转换为 IActionResult” 目前,我尝试了一条 SQL 语句来获取值,但它也不起作用。我将在我的答案中发布我的方法。【参考方案2】:

现在,我尝试了这样的方法:

public IActionResult SaveDetail(List<Cart_Has_Services> cart,double total,string currency)
    
        string payment = @"INSERT INTO Payment(Payment_Method,Currency_Type,Total_Amount) 
                         VALUES('0','1',2);";
        int pay = DBUtl.ExecSQL(payment, "Cash", currency,total);
        if (pay == 1)
        
            object pid = DBUtl.GetList("SELECT Payment_id FROM Payment");
            int paymentid = Convert.ToInt32(pid);

                if (cart.Count() != 0)
        
            string order = @"INSERT INTO [Order](Order_Name,Order_Description,Order_Quantity,Payment_Id) 
                     VALUES('0','1',2,3)";
            foreach (var item in cart)
            
                    int ord = DBUtl.ExecSQL(order, item.Cart_Service, item.Additional_Notes, item.Quantity,paymentid);

目前,代码将通过将值插入支付表来运行。之后,我想获取下一个插入的 payment_id,即订单表。

我尝试获取 payment_id 的方法不起作用。

【讨论】:

又一个错误,不适用于 Object 您能告诉我“DBUtl”产品名称和它的程序集或命名空间,以及您安装的产品版本吗

以上是关于在控制器中为 INSERT 获取标识值(执行插入命令并在 Sql 中返回插入的 Id)的主要内容,如果未能解决你的问题,请参考以下文章

SET IDENTITY_INSERT (Transact-SQL) 允许将显式值插入到表的标识列中

获取标识主键的最新插入值

当 IDENTITY_INSERT 设置为 OFF 时,不能为表中的标识列插入显式值

如何在 Redshift 中打开/关闭 IDENTITY_INSERT

CodeIgniter:如何将 $this->db->insert_id() 值传递给控制器​​以便插入另一个表?

插入标识列identity_insert