Ich habe einige Werte in eine Tabelle eingefügt. Es gibt eine Spalte, deren Wert automatisch generiert wird. In der nächsten Anweisung meines Codes möchte ich diesen Wert abrufen.
Kannst du mir sagen, wie ich es richtig mache?
sql-server
Niyaz
quelle
quelle
Antworten:
@@IDENTITY
ist nicht bereichssicher und bringt Ihnen die ID aus einer anderen Tabelle zurück, wenn Sie einen Insert-Trigger für die ursprüngliche Tabelle haben. Verwenden Sie immerSCOPE_IDENTITY()
quelle
So mache ich meine Speicherprozeduren für MSSQL mit einer automatisch generierten ID.
CREATE PROCEDURE [dbo].[InsertProducts] @id INT = NULL OUT, @name VARCHAR(150) = NULL, @desc VARCHAR(250) = NULL AS INSERT INTO dbo.Products (Name, Description) VALUES (@name, @desc) SET @id = SCOPE_IDENTITY();
quelle
Wenn Sie PHP und MySQL verwenden, können Sie die Funktion mysql_insert_id () verwenden, die Ihnen die ID des gerade eingegebenen Elements mitteilt.
Aber ohne deine Sprache und dein DBMS fotografiere ich hier nur im Dunkeln.
quelle
Dies funktioniert sehr gut in SQL 2005:
DECLARE @inserted_ids TABLE ([id] INT); INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6]) OUTPUT INSERTED.[id] INTO @inserted_ids VALUES (@col1,@col2,@col3,@col4,@col5,@col6)
Es hat den Vorteil, dass alle IDs zurückgegeben werden, wenn Ihre INSERT-Anweisung mehrere Zeilen einfügt.
quelle
Wieder keine sprachunabhängige Antwort, aber in Java geht es so:
quelle
Wenn Sie mit Oracle arbeiten:
Beispiel:
oder wenn Sie von ... Java mit einem CallableStatement anrufen (sry, es ist mein Feld)
und Deklarieren eines Autput-Parameters für die Anweisung
quelle
Es gibt keine Standardmethode (genauso wie es keine Standardmethode zum Erstellen von IDs mit automatischer Inkrementierung gibt). Hier sind zwei Möglichkeiten, dies in PostgreSQL zu tun. Angenommen, dies ist Ihr Tisch:
CREATE TABLE mytable ( id SERIAL PRIMARY KEY, lastname VARCHAR NOT NULL, firstname VARCHAR );
Sie können dies in zwei Anweisungen tun, solange es sich um aufeinanderfolgende Anweisungen in derselben Verbindung handelt (dies ist in PHP mit Verbindungspooling sicher, da PHP die Verbindung zum Pool erst zurückgibt, wenn Ihr Skript fertig ist):
INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George'); SELECT lastval();
lastval () gibt Ihnen den letzten automatisch generierten Sequenzwert an, der in der aktuellen Verbindung verwendet wird.
Die andere Möglichkeit besteht darin, die RETURNING- Klausel von PostgreSQL für die INSERT- Anweisung zu verwenden:
INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;
Dieses Formular gibt eine Ergebnismenge wie eine SELECT- Anweisung zurück und ist auch praktisch, um jede Art von berechnetem Standardwert zurückzugeben.
quelle
Ein wichtiger Hinweis ist, dass die Verwendung von SQL-Abfragen von Anbietern zum Abrufen der zuletzt eingefügten ID sicher ist, ohne dass gleichzeitige Verbindungen befürchtet werden müssen.
Ich dachte immer, Sie müssten eine Transaktion erstellen, um eine Zeile einzufügen, und dann die zuletzt eingefügte ID AUSWÄHLEN, um zu vermeiden, dass eine von einem anderen Client eingefügte ID abgerufen wird.
Diese herstellerspezifischen Abfragen rufen jedoch immer die zuletzt eingefügte ID für die aktuelle Verbindung zur Datenbank ab . Dies bedeutet, dass die zuletzt eingefügte ID nicht von anderen Client-Einfügungen beeinflusst werden kann, solange diese ihre eigene Datenbankverbindung verwenden.
quelle
Für SQL 2005:
Angenommen, die folgende Tabellendefinition:
CREATE TABLE [dbo].[Test]( [ID] [int] IDENTITY(1,1) NOT NULL, [somevalue] [nchar](10) NULL, )
Sie können Folgendes verwenden:
INSERT INTO Test(somevalue) OUTPUT INSERTED.ID VALUES('asdfasdf')
Dies gibt den Wert der ID-Spalte zurück.
quelle
Auf der Website habe ich Folgendes herausgefunden:
SQL SERVER - @@ IDENTITY vs SCOPE_IDENTITY () vs IDENT_CURRENT - Abrufen der zuletzt eingefügten Identität des Datensatzes 25. März 2007 von pinaldave
SELECT @@ IDENTITY Gibt den letzten IDENTITY-Wert zurück, der für eine Verbindung erzeugt wurde, unabhängig von der Tabelle, die den Wert erzeugt hat, und unabhängig vom Umfang der Anweisung, die den Wert erzeugt hat. @@ IDENTITY gibt den zuletzt in Ihrer aktuellen Sitzung in eine Tabelle eingegebenen Identitätswert zurück. Während @@ IDENTITY auf die aktuelle Sitzung beschränkt ist, ist es nicht auf den aktuellen Bereich beschränkt. Wenn Sie einen Auslöser für eine Tabelle haben, der bewirkt, dass eine Identität in einer anderen Tabelle erstellt wird, erhalten Sie die zuletzt erstellte Identität, auch wenn es der Auslöser war, der sie erstellt hat.
SELECT SCOPE_IDENTITY () Gibt den letzten IDENTITY-Wert zurück, der für eine Verbindung und eine Anweisung im selben Bereich erzeugt wurde, unabhängig von der Tabelle, die den Wert erzeugt hat. SCOPE_IDENTITY () gibt wie @@ IDENTITY den zuletzt in der aktuellen Sitzung erstellten Identitätswert zurück, beschränkt ihn jedoch auch auf Ihren aktuellen Bereich. Mit anderen Worten, es wird der letzte Identitätswert zurückgegeben, den Sie explizit erstellt haben, und nicht jede Identität, die durch einen Trigger oder eine benutzerdefinierte Funktion erstellt wurde.
SELECT IDENT_CURRENT ('Tabellenname') Gibt den zuletzt in einer Tabelle erzeugten IDENTITY-Wert zurück, unabhängig von der Verbindung, die den Wert erstellt hat, und unabhängig vom Umfang der Anweisung, die den Wert erzeugt hat. IDENT_CURRENT ist nicht durch Umfang und Sitzung beschränkt. Es ist auf eine bestimmte Tabelle beschränkt. IDENT_CURRENT gibt den Identitätswert zurück, der für eine bestimmte Tabelle in einer Sitzung und einem Bereich generiert wurde.
quelle
Denken Sie daran, dass @@ IDENTITY die zuletzt erstellte Identität für Ihre aktuelle Verbindung zurückgibt, nicht unbedingt die Identität für die zuletzt hinzugefügte Zeile in einer Tabelle. Sie sollten immer SCOPE_IDENTITY () verwenden, um die Identität der kürzlich hinzugefügten Zeile zurückzugeben.
quelle
Welche Datenbank verwenden Sie? Soweit mir bekannt ist, gibt es dafür keine datenbankunabhängige Methode.
quelle
So habe ich es mit parametrisierten Befehlen gemacht.
MSSQL
INSERT INTO MyTable (Field1, Field2) VALUES (@Value1, @Value2); SELECT SCOPE_IDENTITY();
MySQL
INSERT INTO MyTable (Field1, Field2) VALUES (?Value1, ?Value2); SELECT LAST_INSERT_ID();
quelle
sql = "INSERT INTO MyTable (Name) VALUES (@Name);" + "SELECT CAST(scope_identity() AS int)"; SqlCommand cmd = new SqlCommand(sql, conn); int newId = (int)cmd.ExecuteScalar();
quelle
Frau SQL Server: Dies ist eine gute Lösung, auch wenn Sie mehr Zeilen einfügen:
Declare @tblInsertedId table (Id int not null) INSERT INTO Test ([Title], [Text]) OUTPUT inserted.Id INTO @tblInsertedId (Id) SELECT [Title], [Text] FROM AnotherTable select Id from @tblInsertedId
quelle
Robs Antwort wäre die herstellerunabhängigste, aber wenn Sie MySQL verwenden , ist die integrierte
LAST_INSERT_ID()
Funktion die sicherere und korrektere Wahl .quelle
SELECT @@Scope_Identity as Id
Es gibt auch eine @ @ Identität, aber wenn Sie einen Auslöser haben, werden die Ergebnisse von etwas zurückgegeben, das während des Auslösers passiert ist, wobei scope_identity Ihren Bereich respektiert.
quelle
Dies sollte mit jeder Art von Datenbank funktionieren.
quelle
Eine umweltbasierte Oracle-Lösung:
CREATE OR REPLACE PACKAGE LAST AS ID NUMBER; FUNCTION IDENT RETURN NUMBER; END; / CREATE OR REPLACE PACKAGE BODY LAST AS FUNCTION IDENT RETURN NUMBER IS BEGIN RETURN ID; END; END; / CREATE TABLE Test ( TestID INTEGER , Field1 int, Field2 int ) CREATE SEQUENCE Test_seq / CREATE OR REPLACE TRIGGER Test_itrig BEFORE INSERT ON Test FOR EACH ROW DECLARE seq_val number; BEGIN IF :new.TestID IS NULL THEN SELECT Test_seq.nextval INTO seq_val FROM DUAL; :new.TestID := seq_val; Last.ID := seq_val; END IF; END; / To get next identity value: SELECT LAST.IDENT FROM DUAL
quelle
In TransactSQL können Sie die OUTPUT-Klausel verwenden, um dies zu erreichen.
INSERT INTO my_table(col1,col2,col3) OUTPUT INSERTED.id VALUES('col1Value','col2Value','col3Value')
FR: http://msdn.microsoft.com/en-us/library/ms177564.aspx
quelle
Einfachste Antwort:
Standardmäßig wird die erste Spalte zurückgegeben
Rückgabewert Typ: System.Object Die erste Spalte der ersten Zeile in der Ergebnismenge oder eine Nullreferenz (Nothing in Visual Basic), wenn die Ergebnismenge leer ist. Gibt maximal 2033 Zeichen zurück.
Von MSDN kopiert
quelle