अंतिम सम्मिलित आईडी कैसे प्राप्त करें?


174

मेरे पास यह कोड है:

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, जिसे मैं अंतिम सम्मिलित कर सकता हूं इसके बाद मैं उस आईडी का उपयोग दूसरी तालिका में सम्मिलित करने के लिए कर सकता हूं?

जवाबों:


256

SQL सर्वर 2005+ के लिए, यदि कोई आवेषण ट्रिगर नहीं है, तो सम्मिलित विवरण बदलें (सभी एक पंक्ति, यहाँ स्पष्टता के लिए विभाजित करें)

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

SQL सर्वर 2000 के लिए, या यदि कोई आवेषण ट्रिगर है:

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

और तब

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

5
OUTPUT INSERTED.IDमेज पर एक सक्रिय ट्रिगर के मामले में समस्या उत्पन्न कर सकता है
आर्मेन

2
हम्म। जब मैंने यह कोशिश की तो मुझे एक त्रुटि मिली: "ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं है।" भले ही यह Execute के तुरंत बाद चलाया जाता है।
खन्नी

@ अक्षनी क्या आपने इसे ठीक किया?
TuGordoBello

5
'OUTPUT INSERTED.ID' में 'ID' प्राथमिक कुंजी btw है। मुझे लगा कि यह एक आरक्षित शब्द है।
danmbuen

1
@VoidKing: मैं यह कैसे कर सकता हूं .. आप कुछ गलत कर रहे हैं। मदद के लिए नमूना कोड के साथ एक नया प्रश्न पोस्ट करें। जाहिर है, आपने मुझे बताया कि मैं गलत हूं जब यह स्पष्ट रूप से आपके अलावा सभी के लिए काम करता है ...
gbn

38

आप CommandTextबराबर के साथ एक कमांड बना सकते हैं

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

और निष्पादित करें int id = (int)command.ExecuteScalar

MSDN का यह लेख आपको कुछ अतिरिक्त तकनीकें देगा।


6
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();
}

यह vil काम :)


विल? मुझे लगता है कि हमें ईमानदार होने के लिए अधिक व्याकरणिक रूप से सही उत्तर लिखने चाहिए
Zizzipupp

3

मुझे उसी की जरूरत थी और यह जवाब मिला ।।

यह कंपनी तालिका (COMP) में एक रिकॉर्ड बनाता है, यह कंपनी की मेज पर बनाई गई ऑटो आईडी को पकड़ लेता है और कर्मचारी तालिका (स्टाफ) में छोड़ देता है ताकि 2 तालिकाओं को जोड़ा जा सके, MANY कर्मचारी एक कंपनी में। यह मेरी SQL 2008 DB पर काम करता है, SQL 2005 और इसके बाद के संस्करण पर काम करना चाहिए।

===========================

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

- ' @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

- ' OUTPUT डाला गया। 'ऊपर दी गई लाइन का उपयोग किसी भी क्षेत्र के डेटा को रिकॉर्ड करने के लिए किया जाता है जो वह अभी बना रहा है। यह डेटा हम चाहते हैं कि आईडी ऑटोनम्बर हो। तो सुनिश्चित करें कि यह आपकी तालिका के लिए सही फ़ील्ड नाम कहता है, मेरा 'comp_id' है । यह तब हमने पहले बनाई गई टेम्पररी टेबल में गिरा दिया।

  VALUES (@comp_name, @comp_regno, @comp_email)

  SET @recID = (SELECT tempID FROM @tableVar)

- ऊपर दी गई लाइन का उपयोग हमने पहले बनाई गई टेम्पररी टेबल को खोजने के लिए किया है, जहां हमें जिस आईडी की जरूरत है, वह सेव हो गई है। चूंकि इस टेंपरेरी टेबल में केवल एक ही रिकॉर्ड है, और केवल एक फ़ील्ड है, यह केवल आपको आवश्यक आईडी नंबर का चयन करेगा और इसे ' @recID ' में छोड़ देगा । ' @recID ' में अब आपके पास वांछित आईडी संख्या है और आप इसका उपयोग कर सकते हैं कि आप कैसे चाहते हैं जैसे मैंने इसे नीचे उपयोग किया है।

  INSERT INTO staff(Staff_comp_id) 
  VALUES (@recID)

 End

-- तो यह तूम गए वहाँ। आप वास्तव में 'OUTPUT डाले गए। WhatEverFieldNameYouWant' लाइन में जो कुछ भी चाहते हैं, उसे वास्तव में हड़प सकते हैं और अपनी टेंपरेरी टेबल में उन फ़ील्ड्स को बना सकते हैं, जिन्हें आप कभी भी उपयोग करना चाहते हैं।

मैं उम्र के लिए कुछ इस तरह की तलाश कर रहा था, इस विस्तृत विराम के साथ, मुझे आशा है कि यह मदद करता है।


3

शुद्ध एसक्यूएल में मुख्य कथन जैसे:

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

वर्गाकार कोष्ठक सारणी और उसके बाद कॉलम एन और आईडी को परिभाषित करता है, गोल कोष्ठक स्तंभों की गणना को परिभाषित करता है और फिर स्तंभों के लिए मान, मेरे मामले में एक स्तंभ और एक मान। एपोस्ट्रोफ्स एक स्ट्रिंग को संलग्न करता है

मैं आपको अपना दृष्टिकोण समझाऊंगा:

यह समझना आसान नहीं है, लेकिन मुझे उम्मीद है कि अंतिम सम्मिलित आईडी का उपयोग करके बड़ी तस्वीर प्राप्त करने के लिए उपयोगी होगा। बेशक वैकल्पिक आसान दृष्टिकोण हैं। लेकिन मेरे पास मेरे रखने के कारण हैं। संबद्ध कार्य शामिल नहीं हैं, बस उनके नाम और पैरामीटर नाम।

मैं इस पद्धति का उपयोग चिकित्सा कृत्रिम बुद्धिमत्ता के लिए करता हूं। यदि केंद्रीय स्ट्रिंग (1) में वांछित स्ट्रिंग मौजूद है तो विधि की जांच करें। यदि वांछित स्ट्रिंग केंद्रीय तालिका "सिम" में नहीं है, या यदि डुप्लिकेट की अनुमति है, तो वांछित स्ट्रिंग को केंद्रीय तालिका "सिम" (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
    }

2

मैंने ऊपर की कोशिश की, लेकिन उन्होंने काम नहीं किया, मुझे लगा कि यह मेरे लिए ठीक काम करता है।

var ContactID = db.GetLastInsertId();

इसका कम कोड और मुझे इसमें लगाना आसान है।

आशा है कि यह किसी की मदद करता है।


1

आप SQL सर्वर में SCOPE_IDENTITY के लिए कॉल का उपयोग भी कर सकते हैं।


1
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();
        }
    }
}

1

अंतिम सम्मिलित आईडी प्राप्त करने के सभी तरीके हैं, लेकिन सबसे आसान तरीका जो मैंने पाया है वह है डेटासेट में टेबल एडेप्टर से इसे पुनः प्राप्त करना।

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

उम्मीद है की यह मदद करेगा ...


0

किसी भी पंक्ति को सम्मिलित करने के बाद, आप अंतिम सम्मिलित आईडी क्वेरी की रेखा से नीचे प्राप्त कर सकते हैं।

INSERT INTO aspnet_GameProfiles (UserId, GameId) VALUES (@UserId, @GameId); @@ पहचान चुनें



-1

इसके बाद:

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

इसे निष्पादित करें

int id = (int)command.ExecuteScalar;

यह काम करेगा


-2

INSERT INTO aspnet_GameProfiles (UserId, GameId) VALUES (@UserId, @GameId) ", तो आप desc तरीके से तालिका को आदेश देकर अंतिम आईडी तक पहुँच सकते हैं।

TOPI 1 का चयन करें


बशर्ते किसी ने IDENTITY_INSERT का उपयोग नहीं किया हो और बहुत बड़े UserId के साथ एक पंक्ति जोड़ी हो।
ldam

@Logan मैं समझता हूँ, यह आईडी या कुछ मिश्रित (charv + int) जैसे एक चार्वा के साथ काम नहीं कर सकता है, लेकिन आप वृद्धिशील इंट के साथ एक ऐतिहासिक कॉलम सेट कर सकते हैं और उस पर चाल कर सकते हैं।
Aleks

-6
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

यह वही है जो मुझे लगता है कि वास्तव में अच्छा है ..... अब आप एसक्यूएल -2005 में किसी भी तालिका से अंतिम वृद्धि की गई आईडी प्राप्त कर सकते हैं। इसके लिए आपको केवल इस प्रक्रिया को सामने के छोर से कॉल करने की आवश्यकता है। ध्यान दें कि passColumnName में डेटा प्रकार INT होना चाहिए।
दिल की धड़कन

2
स्वीकृत उत्तर के विरुद्ध इस दृष्टिकोण की सबसे बड़ी समस्या यह है कि यदि आप एक ही समय में कई क्लाइंट डेटा डालते हैं तो आप समस्याओं में भाग लेंगे। यदि क्लाइंट एक दो sql कॉल करता है (पहली प्रविष्टि, दूसरी यह संग्रहीत कार्यविधि) और उन दो कॉलों के बीच एक अन्य ग्राहक भी एक सम्मिलित करता है तो आपको गलत आईडी वापस मिल जाएगी!
ओलिवर

4
यह सही परिणाम नहीं लौटाएगा। यह कॉलम में अधिकतम मान लौटाएगा (जिसमें अन्य उपयोगकर्ता या ऑपरेशन सम्मिलित की गई पंक्तियाँ शामिल होंगी) अंतिम मूल्य जिसे आपने डाला है। इसलिए यह केवल सिंगल यूजर सिस्टम पर काम करेगा। बिल्ट इन आईडी प्राप्त करने का एकमात्र सही तरीका है कि संदर्भ के भीतर बिल्ट इन मेथड्स (जैसे स्कोप_सिटी ()) का उपयोग करना।
निकग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.