none
SSMA ACCESS AddNew Autowert RRS feed

  • Frage

  • Hallo SQL-Spezialisten,

    "mühsam nährt sich das Eichhörnchen"

    Nach der Erweiterung des OpenRecordset mit dbOpenDynaset und dbSeeChanges öffnet sich die nächste Falle:
    Neuanlegen eines Datensatzes mit Autowert

    Folgendes Coding hat unter Access die Variable Ergebnis immer mit der Projekt_ID des gerade neu erstellten Datensatzes versorgt: 

    Dim rs_new as DAO.Recordset

    Set rs_new = CurrentDb.OpenRecordset("Projekt", dbOpenDynaset, dbSeeChanges)
        rs_new.AddNew
          Ergebnis = rs_new!Projekt_ID           <== hier kam die neu angelegte ID zurück
          rs_new!Projekt_Titel = "???????"
        rs_new.Update
        rs_new.Close
    set rs_new = nothing

    Läuft das Coding jetzt mit einer SQL-Server-verlinkten "Projekt"-Tabelle ab,
    bleibt Ergebnis = NULL

    Der Datensatz wird zwar mit einer neuen Projekt_ID angelegt, allerdings bekomme ich diese neue Projekt_ID nach dem Anlegen nicht zurückgeliefert!!!!!

    Gibt es andere Methoden, die ich verwenden muß um einen Datensatz neu anzulegen?


    Auch hier würde ich dem Finder der richtigen Antwort gerne ein Bier in München spendieren! :-)
    Vielen Dank für's drüber Nachdenken

    Herzliche Grüße
    Klaus-Jürgen Gruber



    PS:

    Mein Versuch, Ergebnis erst nach dem Update abzufragen ist kontraproduktiv, da dann die Projekt_ID eines (willkürlichen) anderen Datensatzes zurückkommt: 

    Set rs_new = CurrentDb.OpenRecordset("Projekt", dbOpenDynaset, dbSeeChanges)
        rs_new.AddNew
          rs_new!Projekt_Titel = "???????"
        rs_new.Update
          Ergebnis = rs_new!Projekt_ID   <== zweckloser, irritierender Versuch
        rs_new.Close
    set rs_new = nothing



    So ist die Projekt_ID übrigens angelegt:

    in Access:
    Primärschlüssel, 
    Feldgröße: Long Integer
    Neue Werte: Inkrement
    Indiziert: Ja(OhneDuplikate)
    ...

    SSMA hat im SQL-Server für die Projekt_ID folgende Einstellungen erzeugt:
    Datentyp: Int
    Systemtyp: Int
    Primärschlüssel: True
    NULL-Werte zulassen: False
    ...
    ...
    Identität: True
    Identitätsseed: 1
    ID-Inkrement: 1
    ...
    ...




    Montag, 2. Dezember 2019 12:26

Antworten

  • Hallo Leute,

    bitte vielmals um Entschuldigung, daß ich Euch SQL-Server-Spezialisten belästigt habe,
    im ACCESS-Forum (da wo ich eigentlich hätte fragen sollten) gab es die richtige Lösung. 

    rs.bookmark = rs.LastModified muß nach dem rs.Update eingefügt werden, dann ist der
    zuletzt eingefügte Datensatz greifbar und die Projekt_ID vefügbar.

    Siehe: 

    Set rs_new = CurrentDb.OpenRecordset("Projekt", dbOpenDynaset, dbSeeChanges)
        rs_new.AddNew
          rs_new!Projekt_Titel = "???????"
        rs_new.Update
          rs.Bookmark = rs.LastModified <== diese Positionierung muß rein
          Ergebnis = rs_new!Projekt_ID    <== dann klappts mit der neuen ID
        rs_new.Close
    set rs_new = nothing


    Trotzdem nochmals herzlichen Dank für Eure Aufmerksamkeit
    Klaus-Jürgen Gruber
    • Als Antwort markiert KJG_Muenchen Mittwoch, 4. Dezember 2019 09:04
    Mittwoch, 4. Dezember 2019 09:03

Alle Antworten

  • Das Problem bei Identity-Spalten ist, dass die Id erst nach dem Insert vom SQL-Server vergeben wird.
    Die Autonum wird bei Access vor dem Insert vergeben.

    Nach einem rs.Update ist ggf. ein rs.Requery erforderlich um die Daten vom SQL-Server neu abzufragen.
    Wenn allerdings die neue ID nicht im Rahmen des Selects (Open) ist, bekommst du den Satz nicht.
    Allerdings bekommst du ebenso Probleme, wenn du nach dem AddNew einen CancelUpdate versuchst.
    Besser ist es, eine SP anzulegen, die einen neuen Satz leer erstellt und nur die Identity zurückgibt.
    Diese kannst du dann per Open abfragen um den Satz ins Recordset zum Editieren zu bekommen.

    Die SP macht nichts weiter als einen Insert und liefert "SELECT @@IDENTITY" zurück.

    Statt rs.CancelUpdate wäre dann ein rs.Delete erforderlich.

    Montag, 2. Dezember 2019 14:38
  • Vielen Dank,

    da ich noch nie eine SP geschrieben habe, könntest Du mir vielleicht ein Beispiel dafür zeigen und wie ich sie von ACCESS aus aufrufen kann um die ID (Identity) (z.B. Projekt_ID) zu erhalten? 


    Montag, 2. Dezember 2019 15:09
  • In Access definierst du eine Passthru-Abfrage mit dem Befehl:

    exec mySP;

    Als Prozedur definierst du im SQL-Server:

    INSERT INTO my_table DEFAULT VALUES;
    Select
    @@IDENTITY;

    Den Rahmen drumrum findest du bestimmt selber raus.
    https://docs.microsoft.com/de-de/sql/t-sql/statements/create-procedure-transact-sql?view=sql-server-ver15

    Montag, 2. Dezember 2019 15:33
  • Vielen Dank,

    es ist mir gelungen, die SP als PassThru-Query ("Insert_into_Projekt") in meinem Access-Frontend zum Ablauf zu bringen.
    Der Datensatz wird im SQL-Server tatsächlich angelegt.

    Wenn ich die SP im SQL-Server ablaufen lasse erhalte ich im unteren (Ergebnis-)-Bereich auch die neu erzeugte Identity.
    Im Access kann ich die PassThru-Query öffnen (z.B. per Doppelklick), sie läuft ab, erzeugt den neuen Eintrag, liefert aber keinen Returnwert!!
    Wie aber komme ich jetzt an die Identity???
    Versuche wie:
    Ergebnis = CurrentDb.Execute("Insert_into_Projekt")
    oder    
    Set rs_new = CurrentDb.OpenRecordset("Insert_into_Projekt", dbOpenDynaset, dbSeeChanges)
    If Not rs_new.EOF Then
    Ergebnis = rs_new.Fields(0)
    ...
    sind nicht richtig.

    Hast Du noch eine Idee?

    Vielen Dank
    Klaus-Jürgen Gruber


    Hinweis
    Insert_into_Projekt:

    INSERT INTO [dbo].[Projekt] DEFAULT VALUES
    Select @@IDENTITY

                   
    Dienstag, 3. Dezember 2019 14:24
  • Select @@IDENTITY;
    @@IDENTITY kann zu fehlerhaften Ergebnissen führen, das sie die letzte in der ganzen Datenbank vergebene Identity zurück liefert, egal wer eine Datensatz in egal welche Tabelle eingefügt hat, besser SCOPE_IDENTITY (Transact-SQL) verwenden; man beachte die Remarks dort.

    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Dienstag, 3. Dezember 2019 14:49
  • Ggf. musst du noch mal die Eigenschaften der Passthru-Abfrage bemühen und dort einstellen, dass ein Resultset erwartet wird.
    Dienstag, 3. Dezember 2019 16:24
  • Hallo Leute,

    bitte vielmals um Entschuldigung, daß ich Euch SQL-Server-Spezialisten belästigt habe,
    im ACCESS-Forum (da wo ich eigentlich hätte fragen sollten) gab es die richtige Lösung. 

    rs.bookmark = rs.LastModified muß nach dem rs.Update eingefügt werden, dann ist der
    zuletzt eingefügte Datensatz greifbar und die Projekt_ID vefügbar.

    Siehe: 

    Set rs_new = CurrentDb.OpenRecordset("Projekt", dbOpenDynaset, dbSeeChanges)
        rs_new.AddNew
          rs_new!Projekt_Titel = "???????"
        rs_new.Update
          rs.Bookmark = rs.LastModified <== diese Positionierung muß rein
          Ergebnis = rs_new!Projekt_ID    <== dann klappts mit der neuen ID
        rs_new.Close
    set rs_new = nothing


    Trotzdem nochmals herzlichen Dank für Eure Aufmerksamkeit
    Klaus-Jürgen Gruber
    • Als Antwort markiert KJG_Muenchen Mittwoch, 4. Dezember 2019 09:04
    Mittwoch, 4. Dezember 2019 09:03
  • Schön dass Access native eine bessere Lösung bereit hält;-).
    Mittwoch, 4. Dezember 2019 10:41