sql-server - tabelle - sql spalte default wert




SQL: Wie bekomme ich die ID von Werten, die ich gerade eingefügt habe? (14)

  1. Fügen Sie die Zeile mit einer bekannten GUID ein.
  2. Hol das AutoId-Feld mit dieser GUID.

Dies sollte mit jeder Art von Datenbank funktionieren.

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 machen soll?


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 kürzlich hinzugefügte Zeile in einer Tabelle. Sie sollten immer SCOPE_IDENTITY () verwenden, um die Identität der zuletzt hinzugefügten Zeile zurückzugeben.


Eine umgebungsbasierte 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

Eine wichtige Anmerkung ist, dass die Verwendung von Lieferanten-SQL-Abfragen zum Abrufen der zuletzt eingefügten ID sicher ist, ohne dass gleichzeitige Verbindungen in Gefahr sind.

Ich dachte immer, dass Sie eine Transaktion erstellen müssen, um eine Zeile einzufügen und dann die zuletzt eingefügte ID AUSWÄHLEN, um zu vermeiden, dass eine ID von einem anderen Client abgerufen wird.

Diese herstellerspezifischen Abfragen rufen jedoch immer die zuletzt eingefügte ID für die aktuelle Verbindung mit der Datenbank ab . Dies bedeutet, dass die letzte eingefügte ID nicht von anderen Clienteinfügungen beeinflusst werden kann, solange sie ihre eigene Datenbankverbindung verwenden.


Es gibt keine standardmäßige Möglichkeit, dies zu tun (genauso wie es keine standardmäßige Möglichkeit gibt, automatisch inkrementierende IDs zu erstellen). Hier sind zwei Möglichkeiten, dies in PostgreSQL zu tun. Angenommen, das ist dein 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 dem Verbindungspooling sicher, da PHP die Verbindung erst dann zurück zum Pool stellt, wenn Ihr Skript fertig ist):

INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George');
SELECT lastval();

lastval() gibt 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 eignet sich auch für die Rückgabe beliebiger berechneter Standardwerte.


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.


Ms SQL Server: Dies ist eine gute Lösung, selbst 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 

Robs Antwort wäre die herstellerunabhängige, aber wenn Sie MySQL verwenden, wäre die sicherere und korrektere LAST_INSERT_ID() die eingebaute LAST_INSERT_ID() Funktion.


So mache ich meine Store-Prozeduren 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();

Von der Seite habe ich folgende Dinge herausgefunden:

SQL SERVER - @@ IDENTITY vs SCOPE_IDENTITY () vs IDENT_CURRENT - Abrufen der letzten 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 letzten Identitätswert zurück, der in Ihrer aktuellen Sitzung in eine Tabelle eingegeben wurde. Während @@ IDENTITY auf die aktuelle Sitzung beschränkt ist, ist es nicht auf den aktuellen Bereich beschränkt. Wenn Sie einen Trigger für eine Tabelle haben, die dazu führt, dass eine Identität in einer anderen Tabelle erstellt wird, erhalten Sie die Identität, die zuletzt erstellt wurde, selbst 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 erstellt wurde, unabhängig von der Tabelle, die den Wert erzeugt hat. SCOPE_IDENTITY (), wie z. B. @@ IDENTITY, gibt den letzten Identitätswert zurück, der in der aktuellen Sitzung erstellt wurde, 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 eine Identität, die von einem Trigger oder einer benutzerdefinierten Funktion erstellt wurde.

SELECT IDENT_CURRENT ('Tabellenname') Gibt den letzten IDENTITY-Wert zurück, der in einer Tabelle erzeugt wurde, 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 nach Umfang und Sitzung begrenzt; 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 beliebigen Bereich generiert wurde.


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 DBMS schieße ich hier nur in die Dunkelheit.


Wenn Sie mit Oracle arbeiten:

Einfügen in Tabelle (Felder ....) Werte (Werte ...) RETURNING (Liste der Felder ...) INTO (Variablen ...)

Beispiel:

INSERT IN PERSON (NAME) VALUES ('JACK') RETURNING ID_PERSON IN vIDPerson

oder wenn Sie von ... Java mit einer CallableStatement aufrufen (sry, es ist mein Feld)

IN PERSON (NAME) WERTE EINFÜGEN ('JACK') ID_PERSON IN RETURNIEREN?

und Deklarieren eines Autput-Parameters für die Anweisung


@@IDENTITY ist nicht sicher für den Umfang und wird Ihnen die ID aus einer anderen Tabelle zurückgeben, wenn Sie einen Insert-Trigger für die ursprüngliche Tabelle haben, verwenden Sie immer SCOPE_IDENTITY()


SELECT @@Scope_Identity as Id

Es gibt auch @@ identity, aber wenn Sie einen Trigger haben, gibt er die Ergebnisse von etwas zurück, das während des Triggers passiert ist, wobei scope_identity Ihren Bereich respektiert.







sql-server