189 votes

Comment obtenir le dernier identifiant inséré ?

J'ai ce code :

string insertSql = 
    "INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(@UserId, @GameId)";

using (SqlConnection myConnection = new SqlConnection(myConnectionString))
{
   myConnection.Open();

   SqlCommand myCommand = new SqlCommand(insertSql, myConnection);

   myCommand.Parameters.AddWithValue("@UserId", newUserId);
   myCommand.Parameters.AddWithValue("@GameId", newGameId);

   myCommand.ExecuteNonQuery();

   myConnection.Close();
}

Lorsque j'insère dans cette table, j'ai une colonne clé primaire int à incrémentation automatique appelée GamesProfileId Comment puis-je obtenir la dernière insertion après celle-ci afin de pouvoir utiliser cet identifiant pour insérer dans une autre table ?

270voto

gbn Points 197263

Pour SQL Server 2005+, s'il n'y a pas de déclencheur d'insertion, modifiez l'instruction d'insertion (sur une seule ligne, divisée pour plus de clarté) comme suit

INSERT INTO aspnet_GameProfiles(UserId,GameId)
OUTPUT INSERTED.ID
VALUES(@UserId, @GameId)

Pour SQL Server 2000, ou s'il y a un déclencheur d'insertion :

INSERT INTO aspnet_GameProfiles(UserId,GameId) 
VALUES(@UserId, @GameId);
SELECT SCOPE_IDENTITY()

Et puis

 Int32 newId = (Int32) myCommand.ExecuteScalar();

5 votes

OUTPUT INSERTED.ID pourrait générer un problème dans le cas d'un déclencheur actif sur la table

2 votes

Hmm. Quand j'ai essayé ça, j'ai eu une erreur : "Object reference not set to an instance of an object", même si elle est exécutée immédiatement après l'Execute.

0 votes

Je viens d'un milieu mysql, je ne comprends pas cette commande : Int32 newId = (Int32) myCommand.ExecuteScalar();

45voto

Jason Points 125291

Vous pouvez créer un SqlCommand con CommandText égal à

INSERT INTO aspnet_GameProfiles(UserId, GameId) OUTPUT INSERTED.ID VALUES(@UserId, @GameId)

et exécute int id = (int)command.ExecuteScalar .

Este Article de MSDN vous donnera quelques techniques supplémentaires.

4voto

Sim2K Points 36

J'avais le même besoin et j'ai trouvé cette réponse

Cela crée un enregistrement dans la table de la société (comp), il prend l'auto ID créé sur la table de la société et le dépose dans une table du personnel (staff) afin que les 2 tables puissent être liées, beaucoup de personnel à UNE société. Cela fonctionne sur ma base de données SQL 2008, cela devrait fonctionner sur SQL 2005 et plus.

\===========================

CREATE PROCEDURE [dbo].[InsertNewCompanyAndStaffDetails]

 @comp_name varchar(55) = 'Big Company',

 @comp_regno nchar(8) = '12345678',

 @comp_email nvarchar(50) = 'no1@home.com',

 @recID INT OUTPUT

-- Le ' @recID est utilisé pour contenir le numéro d'identification généré automatiquement par la société que nous sommes sur le point de saisir.

AS
 Begin

  SET NOCOUNT ON

  DECLARE @tableVar TABLE (tempID INT)

-- La ligne ci-dessus est utilisée pour créer une table temporaire pour contenir le numéro d'identification généré automatiquement pour une utilisation ultérieure. Il n'y a qu'un seul champ 'tempID' et son type est INT est le même que le @recID .

  INSERT INTO comp(comp_name, comp_regno, comp_email) 

  OUTPUT inserted.comp_id INTO @tableVar

-- Le ' Sortie insérée. La ligne '' ci-dessus est utilisée pour extraire des données de n'importe quel champ de l'enregistrement qu'elle est en train de créer. La donnée que nous voulons est le numéro d'identification automatique. Donc assurez-vous que le nom du champ est correct pour votre table, le mien est comp_id . Il est ensuite déposé dans la table temporaire que nous avons créée plus tôt.

  VALUES (@comp_name, @comp_regno, @comp_email)

  SET @recID = (SELECT tempID FROM @tableVar)

-- La ligne ci-dessus est utilisée pour rechercher la table temporaire que nous avons créée plus tôt, où l'ID dont nous avons besoin est enregistré. Comme il n'y a qu'un seul enregistrement dans cette table temporaire, et qu'un seul champ, elle ne sélectionnera que le numéro d'identification dont vous avez besoin et le déposera dans ' @recID '. ' @recID Vous pouvez l'utiliser comme vous le souhaitez, comme je l'ai fait ci-dessous.

  INSERT INTO staff(Staff_comp_id) 
  VALUES (@recID)

 End

-- Donc voilà. Vous pouvez en fait prendre ce que vous voulez dans le OUTPUT inserted.WhatEverFieldNameYouWant' (Sortie insérée.Quel que soit le nom du champ que vous voulez) et créez les champs que vous voulez dans votre table temporaire et accédez-y pour l'utiliser comme vous le voulez.

J'ai cherché quelque chose comme ça pendant des années, avec cette décomposition détaillée, j'espère que cela vous aidera.

3voto

profimedica Points 371

En SQL pur, l'instruction principale ressemble à :

INSERT INTO [simbs] ([En]) OUTPUT INSERTED.[ID] VALUES ('en')

Les crochets carrés définissent la table simbs et ensuite les colonnes En et ID, les crochets ronds définissent l'énumération des colonnes à initier et ensuite les valeurs pour les colonnes, dans mon cas une colonne et une valeur. Les apostrophes entourent une chaîne de caractères

Je vais vous expliquer ma démarche :

Ce n'est peut-être pas facile à comprendre mais j'espère que c'est utile pour avoir une vue d'ensemble de l'utilisation du dernier identifiant inséré. Bien sûr, il existe d'autres approches plus simples. Mais j'ai des raisons de conserver la mienne. Les fonctions associées ne sont pas incluses, seulement leurs noms et les noms des paramètres.

J'utilise cette méthode pour l'intelligence artificielle médicale La méthode vérifie si la chaîne de caractères recherchée existe dans la table centrale (1). Si la chaîne recherchée n'est pas dans la table centrale "simbs", ou si les doublons sont autorisés, la chaîne recherchée est ajoutée à la table centrale "simbs" (2). Le dernier identifiant inséré est utilisé pour créer la table associée (3).

    public List<int[]> CreateSymbolByName(string SymbolName, bool AcceptDuplicates)
    {
        if (! AcceptDuplicates)  // check if "AcceptDuplicates" flag is set
        {
            List<int[]> ExistentSymbols = GetSymbolsByName(SymbolName, 0, 10); // create a list of int arrays with existent records
            if (ExistentSymbols.Count > 0) return ExistentSymbols; //(1) return existent records because creation of duplicates is not allowed
        }
        List<int[]> ResultedSymbols = new List<int[]>();  // prepare a empty list
        int[] symbolPosition = { 0, 0, 0, 0 }; // prepare a neutral position for the new symbol
        try // If SQL will fail, the code will continue with catch statement
        {
            //DEFAULT und NULL sind nicht als explizite Identitätswerte zulässig
            string commandString = "INSERT INTO [simbs] ([En]) OUTPUT INSERTED.ID VALUES ('" + SymbolName + "') "; // Insert in table "simbs" on column "En" the value stored by variable "SymbolName"
            SqlCommand mySqlCommand = new SqlCommand(commandString, SqlServerConnection); // initialize the query environment
                SqlDataReader myReader = mySqlCommand.ExecuteReader(); // last inserted ID is recieved as any resultset on the first column of the first row
                int LastInsertedId = 0; // this value will be changed if insertion suceede
                while (myReader.Read()) // read from resultset
                {
                    if (myReader.GetInt32(0) > -1) 
                    {
                        int[] symbolID = new int[] { 0, 0, 0, 0 };
                        LastInsertedId = myReader.GetInt32(0); // (2) GET LAST INSERTED ID
                        symbolID[0] = LastInsertedId ; // Use of last inserted id
                        if (symbolID[0] != 0 || symbolID[1] != 0) // if last inserted id succeded
                        {
                            ResultedSymbols.Add(symbolID);
                        }
                    }
                }
                myReader.Close();
            if (SqlTrace) SQLView.Log(mySqlCommand.CommandText); // Log the text of the command
            if (LastInsertedId > 0) // if insertion of the new row in the table was successful
            {
                string commandString2 = "UPDATE [simbs] SET [IR] = [ID] WHERE [ID] = " + LastInsertedId + " ;"; // update the table by giving to another row the value of the last inserted id
                SqlCommand mySqlCommand2 = new SqlCommand(commandString2, SqlServerConnection); 
                mySqlCommand2.ExecuteNonQuery();
                symbolPosition[0] = LastInsertedId; // mark the position of the new inserted symbol
                ResultedSymbols.Add(symbolPosition); // add the new record to the results collection
            }
        }
        catch (SqlException retrieveSymbolIndexException) // this is executed only if there were errors in the try block
        {
            Console.WriteLine("Error: {0}", retrieveSymbolIndexException.ToString()); // user is informed about the error
        }

        CreateSymbolTable(LastInsertedId); //(3) // Create new table based on the last inserted id
        if (MyResultsTrace) SQLView.LogResult(LastInsertedId); // log the action
        return ResultedSymbols; // return the list containing this new record
    }

1voto

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace DBDemo2
{
    public partial class Form1 : Form
    {
        string connectionString = "Database=company;Uid=sa;Pwd=mypassword";
        System.Data.SqlClient.SqlConnection connection;
        System.Data.SqlClient.SqlCommand command;

        SqlParameter idparam = new SqlParameter("@eid", SqlDbType.Int, 0);
        SqlParameter nameparam = new SqlParameter("@name", SqlDbType.NChar, 20);
        SqlParameter addrparam = new SqlParameter("@addr", SqlDbType.NChar, 10);

        public Form1()
        {
            InitializeComponent();

            connection = new System.Data.SqlClient.SqlConnection(connectionString);
            connection.Open();
            command = new System.Data.SqlClient.SqlCommand(null, connection);
            command.CommandText = "insert into employee(ename, city) values(@name, @addr);select SCOPE_IDENTITY();";

            command.Parameters.Add(nameparam);
            command.Parameters.Add(addrparam);
            command.Prepare();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {

            try
            {
                int id = Int32.Parse(textBoxID.Text);
                String name = textBoxName.Text;
                String address = textBoxAddress.Text;

                command.Parameters[0].Value = name;
                command.Parameters[1].Value = address;

                SqlDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    reader.Read();
                    int nid = Convert.ToInt32(reader[0]);
                    MessageBox.Show("ID : " + nid);
                }
                /*int af = command.ExecuteNonQuery();
                MessageBox.Show(command.Parameters["ID"].Value.ToString());
                */
            }
            catch (NullReferenceException ne)
            {
                MessageBox.Show("Error is : " + ne.StackTrace);
            }
            catch (Exception ee)
            {
                MessageBox.Show("Error is : " + ee.StackTrace);
            }
        }

        private void buttonSave_Leave(object sender, EventArgs e)
        {

        }

        private void Form1_Leave(object sender, EventArgs e)
        {
            connection.Close();
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X