Jalankan perintah Sisipkan dan kembalikan Id yang dimasukkan ke dalam Sql


111

Saya memasukkan beberapa nilai ke dalam tabel SQL menggunakan C # di MVC 4. Sebenarnya, saya ingin memasukkan nilai dan mengembalikan 'ID' dari catatan yang terakhir dimasukkan. Saya menggunakan kode berikut.

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

ID secara otomatis bertambah dalam database saat dimasukkan.

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;
        }
    }
}
   

Saya tahu ExecuteNonQuerymenunjukkan angka yang mempengaruhi baris. Daripada yang saya gunakan

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

Tapi itu tidak berhasil. Tolong bantu saya untuk menyelesaikan ini. Dan apakah ada kode seperti cmd.ExecuteInsertAndGetID()(tidak berfungsi dengan kode saya).


Apa maksudmu dengan InsertedID?
Soner Gönül

Jawaban:


211

Solusi berikut akan bekerja dengan sql server 2005 dan yang lebih baru. Anda dapat menggunakan keluaran untuk mendapatkan bidang yang diperlukan. Di tempat id Anda dapat menulis kunci Anda yang ingin Anda kembalikan. lakukan seperti ini

UNTUK SQL SERVER 2005 ke atas

    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;
    }
}

UNTUK versi sebelumnya

    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 diubah = (int) cmd.ExecuteScalar ();
neel

10
Perhatikan bahwa nama kolom harus sesuai dengan nama kolom identitas tabel. Misalnya tabel dengan nama kolom identitas ini: select EmployeeId, * from EmployeesMemerlukan fragmen ini dalam pernyataan sisipan:output inserted.EmployeeId
joshjeppson

Bagaimana Anda akan memeriksa apakah kueri benar-benar menyisipkan dalam kasus ini?
ATD

8
Saya mendapatkan kesalahan cast yang tidak valid saat mencoba mentransmisikan int modified = (int)cmd.ExecuteScalar();ke int. Saya harus menggunakan Convert untuk mengubahnya menjadi int. int modified = Convert.ToInt32(cmd.ExecuteScalar());
Baddack

modifikasi di bawah bekerja untuk saya. INSERT INTO Mem_Basic (Mem_Na, Mem_Occ) output INSERTED.ID VALUES (?,?)
ABB

45

Ubah kueri menjadi

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

Ini akan mengembalikan ID yang dimasukkan terakhir yang kemudian bisa Anda dapatkan ExecuteScalar


1
ini menunjukkan kesalahan "InValidCast Exception tidak ditangani oleh kode pengguna"
neel

2
@neel, itu karena scope_identity () mengembalikan tipe data numerik yang bisa Anda transmisikan hanya terhadap tipe data .net desimal. Cara lain adalah dengan menggunakan rangkaian fungsi Convert.To <datatype> () untuk menghindari masalah cast.
Harsh

2
Jawaban ini lebih baik karena Anda tidak perlu mengetik di kolom ID dari tabel yang akan disisipkan.
goamn

1
SELECT SCOPE_IDENTITY () tidak berfungsi untuk saya, tetapi keluaran INSERTED.ID berfungsi.
TiggerToo

1
@TiggerToo: Versi SQL Server apa yang Anda gunakan? Mungkin saja Microsoft akhirnya tidak lagi digunakan SCOPE_IDENTITY(). OUTPUT INSERTEDmuncul di IIRC SQL Server 2008 dan telah menjadi cara yang disukai untuk melakukannya sejak
Ken Keenan

19

Prosedur tersimpan 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

Kode 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;
}

Saya harap ini akan membantu Anda ....

Anda juga dapat menggunakan ini jika Anda ingin ...

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 : Mengembalikan nilai identitas terakhir yang dimasukkan ke dalam kolom identitas dalam lingkup yang sama. untuk lebih jelasnya http://technet.microsoft.com/en-us/library/ms190315.aspx


3
Akan menyenangkan, tetapi ExecuteNonQuery hanya mengembalikan jumlah baris yang terpengaruh, bukan ID-nya. Gunakan ExecuteScalar sebagai gantinya docs.microsoft.com/en-us/dotnet/api/…
Brandtware
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.