Thực hiện lệnh Chèn và trả về Id đã chèn trong Sql


111

Tôi đang chèn một số giá trị vào bảng SQL bằng C # trong MVC 4. Trên thực tế, tôi muốn chèn giá trị và trả về 'ID' của bản ghi được chèn lần cuối. Tôi sử dụng mã sau đây.

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 lên trong cơ sở dữ liệu khi được chèn vào.

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 ExecuteNonQuerybiể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 nó không hoạt động. Xin hãy giúp tôi giải quyết vấn đề này. Và có mã nào như cmd.ExecuteInsertAndGetID()(không hoạt động với mã của tôi).


Ý bạn là InsertedIDgì?
Soner Gönül

Câu trả lời:


211

Giải pháp sau sẽ hoạt động với sql server 2005 trở lên. Bạn có thể sử dụng đầu ra để lấy trường cần thiết. thay thế id bạn có thể viết khóa của bạn mà bạn muốn trả lại. làm nó 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 các 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 = Convert.ToInt32(cmd.ExecuteScalar());

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

1
int đã sửa đổi = (int) cmd.ExecuteScalar ();
neel

10
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 này cột sắc: select EmployeeId, * from EmployeesĐòi hỏi đoạn này trong báo cáo chèn:output inserted.EmployeeId
joshjeppson

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

8
Tôi đã gặp phải lỗi truyền không hợp lệ khi cố gắng truyền int modified = (int)cmd.ExecuteScalar();tới một int. Tôi đã phải sử dụng Convert để chuyển đổi nó thành một int. int modified = Convert.ToInt32(cmd.ExecuteScalar());
Baddack

sửa đổi dưới đây phù hợp với tôi. INSERT INTO Mem_Basic (Mem_Na, Mem_Occ) đầu ra INSERTED.ID VALUES (?,?)
ABB

45

Thay đổi truy vấn thành

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

Thao tác này sẽ trả về ID được chèn cuối cùng mà bạn có thể nhận được sau đó ExecuteScalar


1
điều này hiển thị lỗi "InValidCast Exception không được xử lý bởi mã người dùng"
neel

2
@neel, đó là vì scope_identity () trả về kiểu dữ liệu số mà bạn chỉ có thể truyền đối với kiểu dữ liệu .net thập phân. Một cách khác là sử dụng chuỗi hàm Convert.To <datatype> () để tránh vấn đề ép kiểu.
Khắc nghiệt

2
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 17/07/17

1
SELECT SCOPE_IDENTITY () không hoạt động với tôi, nhưng đầu ra INSERTED.ID thì có.
TiggerToo,

1
@TiggerToo: Bạn đang sử dụng phiên bản SQL Server nào? Có thể là Microsoft cuối cùng đã không còn nữa SCOPE_IDENTITY(). OUTPUT INSERTEDxuất hiện trong IIRC SQL Server 2008 và đã được cách ưa thích để làm điều đó vì
Ken Keenan

19

Thủ tục lưu trữ SQL Server:

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

Mã C #:

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 những điều này sẽ giúp ích cho bạn ....

Bạn cũng có thể sử dụng cái 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;
        }
    }
}

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.*/

0
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 : Trả về 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. để biết thêm chi tiết http://technet.microsoft.com/en-us/library/ms190315.aspx


3
Sẽ rất hay, nhưng ExecuteNonQuery chỉ trả về số hàng bị ảnh hưởng chứ không phải ID. Sử dụng ExecuteScalar thay docs.microsoft.com/en-us/dotnet/api/...
Brandtware
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.