Führen Sie den Befehl Einfügen aus und geben Sie die eingefügte ID in SQL zurück

111

Ich füge einige Werte mit C # in MVC 4 in eine SQL-Tabelle ein. Eigentlich möchte ich Werte einfügen und die 'ID' des zuletzt eingefügten Datensatzes zurückgeben. Ich benutze den folgenden Code.

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

Die ID wird beim Einfügen automatisch in die Datenbank erhöht.

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

Ich weiß, ExecuteNonQuerybezeichnet die Zahlen, die die Zeile beeinflussen. Stattdessen benutze ich

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

Aber es funktioniert nicht. Bitte helfen Sie mir bei der Lösung dieses Problems. Und gibt es einen Code wie cmd.ExecuteInsertAndGetID()(funktioniert nicht mit meinem Code).

neel
quelle
Was meinst du damit InsertedID?
Soner Gönül
Sie können einen Blick auf stackoverflow.com/questions/9319532/…
Linky

Antworten:

211

Die folgende Lösung funktioniert mit SQL Server 2005 und höher. Sie können die Ausgabe verwenden , um das gewünschte Feld abzurufen. Anstelle der ID können Sie Ihren Schlüssel schreiben, den Sie zurückgeben möchten. mach es so

FÜR SQL SERVER 2005 und höher

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

FÜR frühere Versionen

    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;
    }
}
Ehsan
quelle
1
int modifiziert = (int) cmd.ExecuteScalar ();
Neel
10
Beachten Sie, dass der Spaltenname mit dem Namen der Identitätsspalte der Tabelle übereinstimmen muss. Zum Beispiel eine Tabelle mit diesem Identitätsspaltennamen: select EmployeeId, * from EmployeesErfordert dieses Fragment in der output inserted.EmployeeId
Einfügeanweisung
Wie würden Sie prüfen, ob die Abfrage in diesem Fall tatsächlich eingefügt wurde?
ATD
8
Ich habe einen ungültigen Umwandlungsfehler erhalten, als ich versucht habe, das int modified = (int)cmd.ExecuteScalar();in ein int umzuwandeln. Ich musste Convert verwenden, um es in ein int zu konvertieren. int modified = Convert.ToInt32(cmd.ExecuteScalar());
Baddack
Die folgende Änderung funktioniert für mich. INSERT INTO Mem_Basic (Mem_Na, Mem_Occ) Ausgabe INSERTED.ID VALUES (?,?)
ABB vor
45

Ändern Sie die Abfrage in

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

Dies gibt die zuletzt eingefügte ID zurück, die Sie dann erhalten können ExecuteScalar

Ken Keenan
quelle
1
Dies zeigt einen Fehler "InValidCast Exception wurde vom Benutzercode nicht behandelt"
neel
2
@neel, das liegt daran, dass scope_identity () einen numerischen Datentyp zurückgibt, den Sie nur gegen den dezimalen .net-Datentyp umwandeln können. Eine andere Möglichkeit besteht darin, die Funktionsreihe Convert.To <Datentyp> () zu verwenden, um Cast-Probleme zu vermeiden.
Harte
2
Diese Antwort ist besser, da Sie nicht die ID-Spalte der Tabelle eingeben müssen, in die eingefügt wird.
Goamn
1
SELECT SCOPE_IDENTITY () funktioniert bei mir nicht, die Ausgabe INSERTED.ID jedoch.
TiggerToo
1
@TiggerToo: Welche Version von SQL Server verwenden Sie? Es ist möglich, dass Microsoft endgültig veraltet ist SCOPE_IDENTITY(). OUTPUT INSERTEDerschien in IIRC SQL Server 2008 und ist seitdem der bevorzugte Weg, dies zu tun
Ken Keenan
19

Gespeicherte SQL Server-Prozedur:

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

Ich hoffe diese helfen dir ....

Sie können dies auch verwenden, wenn Sie ...

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;
        }
    }
}
Humayoun Kabir
quelle
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.*/
Sasidharan
quelle
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 : Gibt den letzten Identitätswert zurück, der in eine Identitätsspalte im selben Bereich eingefügt wurde. Weitere Informationen finden Sie unter http://technet.microsoft.com/en-us/library/ms190315.aspx

Ajay
quelle
3
Wäre schön, aber ExecuteNonQuery gibt nur die Anzahl der betroffenen Zeilen zurück, nicht die ID. Verwenden Sie stattdessen ExecuteScalar docs.microsoft.com/en-us/dotnet/api/…
Brandtware