wake-up-neo.net

ID bei INSERT zurückgeben?

Ich habe eine INSERT-Abfrage und möchte, dass die Datenbank die ID der gerade eingefügten Zeile zurückgibt.

sqlString = "INSERT INTO MagicBoxes (OwnerID, Key, Name, Permissions, Active, LastUpdated) VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) SET @ID = SCOPE_IDENTITY();";
cmd = new SqlCommand(sqlString, con);
cmd.Parameters.AddWithValue("@OwnerID", OwnerID);
cmd.Parameters.AddWithValue("@BoxKey", BoxKey);
cmd.Parameters.AddWithValue("@BoxName", BoxName);
cmd.Parameters.AddWithValue("@Username", Username);
cmd.Parameters.AddWithValue("@Date", DateTime.Now);
cmd.ExecuteNonQuery();

Ich habe derzeit das, ich bin mir nicht sicher, was ich als nächstes tun muss ...

23
Danpe

Sie müssen lediglich @ID zur Params-Sammlung hinzufügen und diese dann so abrufen 

cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
//Now just read the value of: cmd.Parameters["@ID"].value

Oder, wenn Sie diese Syntax bevorzugen:

SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4);
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
33
AdaTheDev

Sie haben zwei Möglichkeiten. Sie könnten einen Output-Parameter mit dem Namen @ID angeben. oder - Sie könnten das Ende in SELECT SCOPE_IDENTITY() ändern und einfach Folgendes verwenden:

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

Ich bevorzuge den formalen Parameter-Ansatz, aber ExecuteScalar funktioniert gut.

21
Marc Gravell

Seit SQL Server 2008 wurde die Syntax von TSQL um eine OUTPUT-Klausel erweitert. Auf diese Weise können Sie die Daten, die von der DML-Abfrage betroffen sind, dem Tabellendatenstrom hinzufügen. 

Das Abfragen von SCOPE_IDENTITY () nach einer Abfrage gibt zwar die richtigen Informationen zurück, zwingt SQL Server jedoch, zwei Abfragen auszuführen, bei denen die Ausgabeklausel dies auf eine Abfrage beschränkt. 

Wenn Sie wissen, kann die Abfrage, die ausgeführt wird, wie folgt geändert werden (Angenommen, [Id] ist der Name der Identität):

INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
OUTPUT INSERTED.Id
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date)

Ein weiteres Problem besteht nicht darin, die SqlCommand zu entsorgen. Die meisten Sql...-Objekte in ADO.net implementieren IDisposable und sollten ordnungsgemäß entsorgt werden.

Um alles zusammenzubringen, würde ich diesen Code folgendermaßen implementieren:

        using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString))
        using (var cmd = new SqlCommand(@"
                INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
                OUTPUT INSERTED.Id
                VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) ", conn))
        {
            cmd.Parameters.AddRange(new[]
                {
                    new SqlParameter("@OwnerID", SqlDbType.Int).Value = OwnerID,
                    new SqlParameter("@BoxKey", SqlDbType.VarChar).Value = BoxKey, 
                    new SqlParameter("@BoxName", SqlDbType.VarChar).Value = BoxName, 
                    new SqlParameter("@Date", SqlDbType.DateTime).Value = DateTime.Now 
                });

            conn.Open();

            var id = (int)cmd.ExecuteScalar();
        }
16
Filip De Vos

Fügen Sie dies Ihren Parametern hinzu

SqlParameter IDParameter = new SqlParameter("@ID",SqlDbType.Int);
IDParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(IDParameter);

Nach der Ausführung können Sie die ID abrufen 

int id = (int)IDParameter.Value;
5
RemoteSojourner

Warum rufen Sie nicht die Store-Prozedur auf. Übergeben Sie Werte an die Speicherprozedur, um die eingefügten Werte zu erhalten, und geben Sie über SP den letzten mit SCOPE_IDENTITY(). eingefügten Startwert zurück.

0
FIre Panda