Announcement

Collapse
No announcement yet.

letzte Datensatz ID ermitteln (MS SQL-Server)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • letzte Datensatz ID ermitteln (MS SQL-Server)

    Hallo!

    Gibt es eine Methode in .NET/ADO.NET die nach Ausführung des SQL-Kommandos (INSERT) die aktuelle ID (auto increment) zurückgibt?

    In PHP bzw. mit mySQL bekam man mit der Funktion "mysql_insert_id()" die ID des vorab eingetragenen Datensatzes zurück. Hat der MS SQL-Server auch so eine Funktion? Oder kann man das doch mit ADO.NET lösen?

    Momentan sende ich ein zweites SQL-Kommando (MAX) nach dem INSERT-SQL-Kommando um die höchste bzw. letzte ID zu ermitteln. Das ist aber irgendwie keine zufrieden stellende Lösung.

    Vielen Dank im Voraus!

    Stefan

  • #2
    Hallo,

    >Momentan sende ich ein zweites SQL-Kommando (MAX) nach dem INSERT-SQL-Kommando...

    das ist völlig unnötig, denn der MS SQL Server unterstützt eine so genannten <i>Batch-Anweisung</i> (alias Stapelanweisung), um mehrere SQL-Anweisungen auf ein Mal auszuführen.

    Der SqlDataAdapter-Wizard von VS.NET baut zum Beispiel die folgende Batch-Anweisung automatisch zusammen, damit der neue IDENTITY-Wert des MS SQL Server sofort nach dem INSERT automatisch im DataSet (DataTable) auftaucht. Die nachfolgende SELECT-Abfrage wird von einem Semikolon von der ersten Anweisung abgetrennt. Über die MS SQL Server-Funktion <b>@@IDENTITY</b> wird garantiert der von INSERT neu eingefügte Datensatz gefunden. Auch wenn, wenn ein Trigger etc. Änderungen vornimmt, erhält das DataSet automatisch die aktuellste Sicht auf die Daten:
    <pre>
    INSERT INTO NETTable(Vorname, Nachname, PLZ) VALUES (@Vorname, @Nachname, @PLZ);
    SELECT KdnID, Vorname, Nachname, PLZ FROM NETTable WHERE (KdnID = @@IDENTITY);
    </pre>

    Eine alternative Technik besteht darin, den neuen Datensatz über eine <i>Stored Procedure</i> anlegen zu lassen, wobei die gespeicherte Prozedur den neuen Primärschlüsselwert (IDENTITY-Spalte) ebenfalls über @@IDENTITY ermittelt und über die <b>Return</b>-Anweisung als eigenen Rückgabewert an den Aufrufer liefert

    Comment


    • #3
      Ab dem SQL Server 2000 gibt's übrigens neu auch die Funktion SCOPE_IDENTITY(), die nicht empfindlich auf nicht sichtbare Hintergrundaktionen wie Triggers ist

      Comment


      • #4
        Hallo und erstmal Danke!<p> Das ist doch eine wesentlich schöner Lösung als meine!
        Ich musste die letzten Tage erstmal mich mit den Begrifflichkeiten des SQL Server vertraut machen und die Lösungsvorschläge ausprobieren.
        <PRE>// 1
        string abfrage = "INSERT INTO NETTable (Vorname, Name) VALUES (' "+ @KdnVorname.Value + " ', ' " + @KdnName.Value + " '); SELECT @@IDENTITY";</PRE><PRE>SqlCommand sqlCmd = new SqlCommand(abfrage, Conn);
        int ID = Convert.ToInt32(sqlCmd.ExecuteScalar());
        Conn.Close();
        </PRE>

        fragen zu 1.
        Ist das eine so genannte Batch-Anweisung?

        Man könnte in der SQL-Anweisung statt <i> SELECT @@IDENTITY</i> auch
        <i>SELECT IDENT_CURRENT('NETTable')</i> oder <i>SELECT SCOPE_IDENTITY()</i> schreiben. Welcher dieser Lösungen ist die schnellste und sicherste?

        Die Variante mit <i>SCOPE_IDENTITY()</i>, oder? (zu mindestens die sicherste)

        Auszug aus der Onlinedokumentation des SQL Servers:
        "@@IDENTITY und SCOPE_IDENTITY geben den letzten Identitätswert zurück, der in einer Tabelle in der aktuellen Sitzung generiert wurde. Allerdings gibt SCOPE_IDENTITY den Wert nur im aktuellen Gültigkeitsbereich zurück, @@IDENTITY ist nicht auf einen bestimmten Gültigkeitsbereich begrenzt."

        Ist der Gültigkeitsbereich in diesem Fall die Batch-Anweisung? Der Gültigkeitsbereich könnte aber auch eine Gespeicherte Prozedur (Stored Procedures) oder ein Trigger sein, richtig?

        Dann hätte ich noch Fragen zu Gespeicherten Prozeduren (Stored Procedures) und Triggers.

        In der Onlinedokumentation des SQL Servers steht bei "Gespeicherte Prozeduren und Trigger" das sie die Performance verbessern.

        Sollte man nicht immer Gespeicherte Prozeduren oder Triggers bei INSERT, UPDATE und DELETE verwenden? Da es ja die Performance verbessert und ist ja schon ein Argument. Aber wo liegen die Nachteile? Wann sollte man sie einsetzen? Und wann nicht

        Comment


        • #5
          Hallo,

          &gt;..die schnellste ...

          @@identity

          &gt;..sicherste

          IDENT_CURRENT, wenn man Änderungen durch später hinzugefügte Trigger ausblenden möchte, die selbst neue Datensätze in anderen Tabellen anlegen

          &gt;...Gültigkeitsbereich...

          Man ist auf dem sicheren Weg, wenn als Gültigkeitsbereich die aktuelle Transaktion der eigenen Datenbank-Session betrachtet wird. Mit einer Datenbank-Session ist die Verbindung zur Datenbank gemeint, solange diese nicht geschlossen wird, handelt es sich um die gleiche Session.

          &gt;Sollte man nicht immer Gespeicherte Prozeduren verwenden..

          Ja.

          &gt;Aber wo liegen die Nachteile?

          Bisher war das für uns als Entwickler mit einem deutlich höheren Aufwand verbunden: <br>
          a) Stored Procedure mit den ganzen INPUT- und OUTPUT-Parametern in der Datenbank deklarieren <br>
          b) Parameters-Kollektion des Command-Objekts für den Aufruf der Stored Procedure füllen. <br>
          Aber seit VS.NET übernimmt beide Aufgaben der Wizard vom SqlDataAdapter in eigener Regie, so dass die Sache für uns sehr einfach und vor allem sehr sicher (keine Verwechselung von Reihenfolge und Typ der Parameter) wird

          Comment

          Working...
          X