2013-08-22 24 views
60

Xin chào, tôi đang chèn một số giá trị vào bảng sql bằng C# trong MVC4. Trên thực tế tôi muốn chèn các giá trị và trả về 'ID' của bản ghi được chèn lần cuối. Tôi sử dụng đoạn mã sau.Thực hiện lệnh Chèn và trả về Id được chèn trong Sql

public class MemberBasicData 
{ 
    public int Id { get; set; } 
    public string Mem_NA { get; set; } 
    public string Mem_Occ { get; set; }  
} 

ID được tự động tăng trong cơ sở dữ liệu khi được chèn.

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    using (SqlConnection con=new SqlConnection(Config.ConnectionString)) 
    { 
     using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ)",con)) 
     { 
      cmd.Parameters.AddWithValue("@na", Mem_NA); 
      cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
      con.Open(); 

      int modified = cmd.ExecuteNonQuery(); 

      if (con.State == System.Data.ConnectionState.Open) con.Close(); 
       return modified; 
     } 
    } 
} 

Tôi biết ExecuteNonQuery biểu thị các số ảnh hưởng đến hàng. Thay vào đó, tôi sử dụng

int modified = (int)cmd.ExecuteScalar(); 

Nhưng không hoạt động. Xin hãy giúp tôi giải quyết vấn đề này. Và có bất kỳ mã như cmd.ExecuteInsertAndGetID() (không làm việc với mã của tôi).

+0

Ý của bạn là gì với 'InsertedID'? –

+0

Bạn có thể xem http://stackoverflow.com/questions/9319532/return-value-from-sql-server-insert-command-using-c-sharp – Linky

Trả lời

107

Các giải pháp sau đây sẽ làm việc với SQL Server 2005 trở lên. Bạn có thể sử dụng output để nhận được trường bắt buộc. tại chỗ id bạn có thể viết khóa của bạn mà bạn muốn quay trở lại. làm điều đó như thế này

cho SQL Server 2005 trở lên

using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) output INSERTED.ID VALUES(@na,@occ)",con)) 
    { 
     cmd.Parameters.AddWithValue("@na", Mem_NA); 
     cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
     con.Open(); 

     int modified =(int)cmd.ExecuteScalar(); 

     if (con.State == System.Data.ConnectionState.Open) 
      con.Close(); 

     return modified; 
    } 
} 

CHO phiên bản trước

using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ);SELECT SCOPE_IDENTITY();",con)) 
    { 
     cmd.Parameters.AddWithValue("@na", Mem_NA); 
     cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
     con.Open(); 

     int modified = cmd.ExecuteScalar(); 

     if (con.State == System.Data.ConnectionState.Open) con.Close(); 
      return modified; 
    } 
} 
+1

int modified = (int) cmd.ExecuteScalar(); – neel

+7

Lưu ý rằng tên cột phải khớp với tên cột nhận dạng của bảng.Ví dụ một bảng với tên cột nhận dạng này: 'select EmployeeId, * from Employees' Yêu cầu đoạn này trong câu lệnh chèn:' output inserted.EmployeeId' – joshjeppson

+0

Làm thế nào bạn kiểm tra xem truy vấn có thực sự chèn vào trong trường hợp này không? – ATD

24

Thay đổi truy vấn để

"INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ); SELECT SCOPE_IDENTITY()" 

này sẽ trả lại ID chèn vào cuối mà sau đó bạn có thể nhận được với ExecuteScalar

+1

điều này cho thấy lỗi "Ngoại lệ InValidCast bị người dùng hủy bỏ mã " – neel

+1

@neel, đó là vì scope_identity() trả về kiểu dữ liệu số mà bạn có thể truyền chỉ dựa vào kiểu dữ liệu thập phân .net. Một cách khác là sử dụng Convert.To () loạt các chức năng để tránh sự cố truyền. – Harsh

+1

Câu trả lời này tốt hơn vì bạn không phải nhập cột ID của bảng đang được chèn vào. – goamn

0
USE AdventureWorks2012; 
GO 
IF OBJECT_ID(N't6', N'U') IS NOT NULL 
    DROP TABLE t6; 
GO 
IF OBJECT_ID(N't7', N'U') IS NOT NULL 
    DROP TABLE t7; 
GO 
CREATE TABLE t6(id int IDENTITY); 
CREATE TABLE t7(id int IDENTITY(100,1)); 
GO 
CREATE TRIGGER t6ins ON t6 FOR INSERT 
AS 
BEGIN 
    INSERT t7 DEFAULT VALUES 
END; 
GO 
--End of trigger definition 

SELECT id FROM t6; 
--IDs empty. 

SELECT id FROM t7; 
--ID is empty. 

--Do the following in Session 1 
INSERT t6 DEFAULT VALUES; 
SELECT @@IDENTITY; 
/*Returns the value 100. This was inserted by the trigger.*/ 

SELECT SCOPE_IDENTITY(); 
/* Returns the value 1. This was inserted by the 
INSERT statement two statements before this query.*/ 

SELECT IDENT_CURRENT('t7'); 
/* Returns value inserted into t7, that is in the trigger.*/ 

SELECT IDENT_CURRENT('t6'); 
/* Returns value inserted into t6. This was the INSERT statement four statements before this query.*/ 

-- Do the following in Session 2. 
SELECT @@IDENTITY; 
/* Returns NULL because there has been no INSERT action 
up to this point in this session.*/ 

SELECT SCOPE_IDENTITY(); 
/* Returns NULL because there has been no INSERT action 
up to this point in this scope in this session.*/ 

SELECT IDENT_CURRENT('t7'); 
/* Returns the last value inserted into t7.*/ 
1
using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) " + 
    "VALUES(@na,@occ);SELECT SCOPE_IDENTITY();",con)) 
{ 
    cmd.Parameters.AddWithValue("@na", Mem_NA); 
    cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
    con.Open(); 

    int modified = cmd.ExecuteNonQuery(); 

    if (con.State == System.Data.ConnectionState.Open) con.Close(); 
     return modified; 
} 

SCOPE_IDENTITY: Retur ns giá trị nhận dạng cuối cùng được chèn vào cột nhận dạng trong cùng phạm vi. thủ tục để biết thêm chi tiết http://technet.microsoft.com/en-us/library/ms190315.aspx

+1

Sẽ tốt đẹp, nhưng ExecuteNonQuery chỉ trả về số hàng bị ảnh hưởng, chứ không phải ID. Sử dụng ExecuteScalar thay vì https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executenonquery?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query % 3FappId% 3DDev15IDEF1% 26l% 3DEN-US% 26k% 3Dk (System.Data.SqlClient.SqlCommand.ExecuteNonQuery); k (SolutionItemsProject); k (TargetFrameworkMoniker-.NETFramework, Phiên bản% 3Dv4.6.2); k (DevLang-csharp)% 26rd% 3Dtrue & view = netframework-4.7.1 – Brandtware

9

SQL Server lưu trữ:

CREATE PROCEDURE [dbo].[INS_MEM_BASIC] 
    @na varchar(50), 
    @occ varchar(50), 
    @New_MEM_BASIC_ID int OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO Mem_Basic 
    VALUES (@na, @occ) 

    SELECT @New_MEM_BASIC_ID = SCOPE_IDENTITY() 
END 

C# code:

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    // values 0 --> -99 are SQL reserved. 
    int new_MEM_BASIC_ID = -1971; 
    SqlConnection SQLconn = new SqlConnection(Config.ConnectionString); 
    SqlCommand cmd = new SqlCommand("INS_MEM_BASIC", SQLconn); 

    cmd.CommandType = CommandType.StoredProcedure; 

    SqlParameter outPutVal = new SqlParameter("@New_MEM_BASIC_ID", SqlDbType.Int); 

    outPutVal.Direction = ParameterDirection.Output; 
    cmd.Parameters.Add(outPutVal); 
    cmd.Parameters.Add("@na", SqlDbType.Int).Value = Mem_NA; 
    cmd.Parameters.Add("@occ", SqlDbType.Int).Value = Mem_Occ; 

    SQLconn.Open(); 
    cmd.ExecuteNonQuery(); 
    SQLconn.Close(); 

    if (outPutVal.Value != DBNull.Value) new_MEM_BASIC_ID = Convert.ToInt32(outPutVal.Value); 
     return new_MEM_BASIC_ID; 
} 

Tôi hy vọng chúng sẽ giúp bạn ....

Bạn cũng có thể sử dụng này nếu bạn muốn ...

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    using (SqlConnection con=new SqlConnection(Config.ConnectionString)) 
    { 
     int newID; 
     var cmd = "INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ);SELECT CAST(scope_identity() AS int)"; 

     using(SqlCommand cmd=new SqlCommand(cmd, con)) 
     { 
      cmd.Parameters.AddWithValue("@na", Mem_NA); 
      cmd.Parameters.AddWithValue("@occ", Mem_Occ); 

      con.Open(); 
      newID = (int)insertCommand.ExecuteScalar(); 

      if (con.State == System.Data.ConnectionState.Open) con.Close(); 
       return newID; 
     } 
    } 
}