Как получить последний вставленный идентификатор?
у меня есть этот код:
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();
}
когда я вставляю в эту таблицу, у меня есть столбец первичного ключа auto_increment int с именем GamesProfileId, Как я могу получить последний вставленный после этого, чтобы я мог использовать этот идентификатор для вставки в другую таблицу?
15 ответов:
для SQL Server 2005+, если нет триггера insert, то измените инструкцию insert (все одна строка, разделенная для ясности здесь) на this
INSERT INTO aspnet_GameProfiles(UserId,GameId) OUTPUT INSERTED.ID VALUES(@UserId, @GameId)для SQL Server 2000 или если есть триггер Insert:
INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(@UserId, @GameId); SELECT SCOPE_IDENTITY()а то
Int32 newId = (Int32) myCommand.ExecuteScalar();
вы можете создать команду с
CommandTextравнаINSERT INTO aspnet_GameProfiles(UserId, GameId) OUTPUT INSERTED.ID VALUES(@UserId, @GameId)и выполнить
int id = (int)command.ExecuteScalar.этой статья MSDN даст вам некоторые дополнительные методы.
string insertSql = "INSERT INTO aspnet_GameProfiles(UserId,GameId) VALUES(@UserId, @GameId)SELECT SCOPE_IDENTITY()"; int primaryKey; using (SqlConnection myConnection = new SqlConnection(myConnectionString)) { myConnection.Open(); SqlCommand myCommand = new SqlCommand(insertSql, myConnection); myCommand.Parameters.AddWithValue("@UserId", newUserId); myCommand.Parameters.AddWithValue("@GameId", newGameId); primaryKey = Convert.ToInt32(myCommand.ExecuteScalar()); myConnection.Close(); }эта работа Виль :)
у меня была такая же потребность и нашел этот ответ ..
Это создает запись в таблице компании (comp), она захватывает автоматический идентификатор, созданный на таблице компании, и отбрасывает его в таблицу персонала (персонал), поэтому 2 таблицы могут быть связаны, многие сотрудники с одной компанией. Он работает на моей БД SQL 2008, должен работать на SQL 2005 и выше.
===========================
CREATE PROCEDURE [dbo].[InsertNewCompanyAndStaffDetails] @comp_name varchar(55) = 'Big Company', @comp_regno nchar(8) = '12345678', @comp_email nvarchar(50) = '[email protected]', @recID INT OUTPUT-- The'@recID' используется для хранения автоматически сгенерированного идентификационного номера компании что мы собираемся захватить
AS Begin SET NOCOUNT ON DECLARE @tableVar TABLE (tempID INT)-- строка выше используется для создания временной таблицы для хранения автоматически сгенерированного идентификационного номера для последующего использования. Он имеет только одно поле 'tempID' и его тип INT такой же '@recID'.
INSERT INTO comp(comp_name, comp_regno, comp_email) OUTPUT inserted.comp_id INTO @tableVar-- The'выход вставлен.' строка выше используется для захвата данных из любого поля в записи, которую он создает прямо сейчас. Эти данные, которые мы хотим, - это автономер идентификатора. Поэтому убедитесь, что он говорит правильное имя поля для вашей таблицы, мое - 'comp_id'. Это затем отбрасывается в таблицу tempory, которую мы создали ранее.
VALUES (@comp_name, @comp_regno, @comp_email) SET @recID = (SELECT tempID FROM @tableVar)-- строка выше используется для поиска временной таблицы, которую мы создали ранее, где сохраняется идентификатор, который нам нужен. Поскольку в этой временной таблице есть только одна запись и только одно поле, он выберет только нужный вам идентификационный номер и опустит его в '@recID'. - @recID' теперь имеет идентификационный номер, который вы хотите, и вы можете используйте его, как вы хотите, как я использовал его ниже.
INSERT INTO staff(Staff_comp_id) VALUES (@recID) End-- так что вы идете. Вы можете на самом деле захватить то, что вы хотите в 'вставить.WhatEverFieldNameYouWant' постройте и создайте поля, которые вы хотите в своей временной таблице, и получите доступ к ней, чтобы использовать ее как угодно.
Я искал что-то подобное целую вечность, с этим подробным перерывом, я надеюсь, что это поможет.
в чистом SQL основное утверждение kools нравится:
INSERT INTO [simbs] ([En]) OUTPUT INSERTED.[ID] VALUES ('en')квадратные скобки определяют табличные символы, а затем столбцы En и ID, круглые скобки определяют перечисление столбцов, которые будут инициированы, а затем значения для столбцов, в моем случае один столбец и одно значение. Апострофы заключают строку
я объясню вам мой подход:
это может быть нелегко понять, но я надеюсь, что полезно получить общую картину вокруг использования последнего вставленного идентификатор. Конечно, есть и другие, более простые подходы. Но у меня есть причины сохранить свои. Связанные функции не включены, только их имена и имена параметров.
Я использую этот метод для медицинского искусственного интеллекта Метод проверяет, существует ли нужная строка в центральной таблице (1). Если нужная строка не находится в центральной таблице "simbs", или если дубликаты разрешены, то нужная строка добавляется в центральную таблицу "simbs" (2). Последний неразделенный идентификатор используется для создания связанные таблицы (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 }
Я пробовал выше, но они не работали, я нашел эту мысль, что работает просто отлично для меня.
var ContactID = db.GetLastInsertId();его меньше кода и я легко поставить.
надеюсь, это кому-то поможет.
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(); } } }
есть всевозможные способы получить последний вставленный идентификатор, но самый простой способ, который я нашел, - это просто получить его из адаптера таблицы в наборе данных следующим образом:
<Your DataTable Class> tblData = new <Your DataTable Class>(); <Your Table Adapter Class> tblAdpt = new <Your Table Adapter Class>(); /*** Initialize and update Table Data Here ***/ /*** Make sure to call the EndEdit() method ***/ /*** of any Binding Sources before update ***/ <YourBindingSource>.EndEdit(); //Update the Dataset tblAdpt.Update(tblData); //Get the New ID from the Table Adapter long newID = tblAdpt.Adapter.InsertCommand.LastInsertedId;надеюсь, это поможет ...
после этого:
INSERT INTO aspnet_GameProfiles(UserId, GameId) OUTPUT INSERTED.ID VALUES(@UserId, @GameId)выполнить этот
int id = (int)command.ExecuteScalar;Он будет работать
после вставки любой строки вы можете получить последний вставленный идентификатор ниже строки запроса.
вставить в aspnet_GameProfiles(UserId, GameId) Значения (@UserId, @GameId); ВЫБЕРИТЕ @ @ IDENTITY
если Ваш идентификатор типа int и установлен на автоматическое увеличение, то попробуйте этот
SELECT * FROM TABLE WHERE ID = (SELECT MAX(ID) FROM TABLE)
вставить в aspnet_GameProfiles (UserId,GameId) значения (@UserId, @GameId)"; затем вы можете просто получить доступ к последнему идентификатору, заказав таблицу способом desc.
выбрать первые 1 userId от того, aspnet_GameProfiles имени пользователя деск.
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO CREATE PROC [dbo].[spCountNewLastIDAnyTableRows] ( @PassedTableName as NVarchar(255), @PassedColumnName as NVarchar(225) ) AS BEGIN DECLARE @ActualTableName AS NVarchar(255) DECLARE @ActualColumnName as NVarchar(225) SELECT @ActualTableName = QUOTENAME( TABLE_NAME ) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @PassedTableName SELECT @ActualColumnName = QUOTENAME( COLUMN_NAME ) FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = @PassedColumnName DECLARE @sql AS NVARCHAR(MAX) SELECT @sql = 'select MAX('+ @ActualColumnName + ') + 1 as LASTID' + ' FROM ' + @ActualTableName EXEC(@SQL) END
Comments