Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Transaktion (Zähler erhöhen & anschliessendes INSERT) (https://www.delphipraxis.net/75357-transaktion-zaehler-erhoehen-anschliessendes-insert.html)

Fellmer Lloyd 18. Aug 2006 10:16

Datenbank: MS SQL • Version: 2005 • Zugriff über: ADO

Transaktion (Zähler erhöhen & anschliessendes INSERT)
 
Hallo Alle!

Ich arbeite mit folgender Datenbank:
- MS SQL 2005 Standard
- Zugriff per ADO (aus VB)

Ich habe zwei Tabellen erstellt.
Die erste (TestCounter) enthält mehrere Zähler, allerdings ist nur einer relevant.
http://nathan-systems.ch/images/TabelleCounter.gif

Die zweite Tabelle (TestTable) enthält Datensätze, welche jeweils einen Eindeutigen Zählerwert enthalten sollen.
D.h. ich will neben der Tabellen ID einen weiteren Wert, welcher durchlaufend nummeriert wird.
Diese Tabelle wird später mit weiteren Informationsfeldern ergänzt (Name, Adresse usw.).
http://nathan-systems.ch/images/TabelleTest.gif

Bei jedem neuen Datensatz in der Tabelle "TestTable" soll der Zähler erhöht werden und ins Insert eingebunden werden.
Da ich keine Datensätze ohne Zähler-Wert und keine Lücken in der Zählerfolge haben will, möchte ich das ganze gerne per Transaktion lösen.
D.h. falls etwas schief geht (Programmfehler, Ungültige Daten, Server brennt ab, User zieht den Stecker usw. :) ) soll alles rückgängig gemacht werden (keine Änderung der Daten).

Leider kenne ich mich mit solchen Transaktionen nicht aus... könnt ihr mir da weiterhelfen?
Das SQL Query habe ich soweit schon erstellt:
SQL-Code:
-- Deklarationen
DECLARE @NewCountValue int
DECLARE curNewCount CURSOR FOR SELECT [Value] FROM dbo.TestCounter WHERE ID = 'TestCounter'

-- Zähler erhöhen
UPDATE
  dbo.TestCounter
SET
  [Value] = (SELECT MAX(Value)+1 FROM TestCounter WHERE ID = 'TestCounter')
WHERE
  ID = 'TestCounter'

-- Cursor öffnen & neuen (erhöhter) Wert auslesen
OPEN curNewCount
IF @@Cursor_Rows <> 0
BEGIN
  FETCH NEXT FROM curNewCount INTO @NewCountValue  
END

-- Tabelleneintrag mit neuem Wert erstellen
INSERT INTO dbo.TestTable (IdCount) VALUES (@NewCountValue)

-- Cursor schliessen freigeben
CLOSE curNewCount
DEALLOCATE curNewCount

--SELECT @NewCountValue
Wie kann ich dieses Query nun als sichere Transaktion verpacken (Commit usw.)?
Wie sieht es aus, wenn mehrere Benutzer gleichzeitig einen Datensatz erstellen?

Danke im Vorraus!

Gruss Fellmer

mkinzler 18. Aug 2006 10:20

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Unterstützt MSSQl keine Sequenzen?

Jelly 18. Aug 2006 10:23

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Zitat:

Zitat von Fellmer Lloyd
Bei jedem neuen Datensatz in der Tabelle "TestTable" soll der Zähler erhöht werden und ins Insert eingebunden werden.
Da ich keine Datensätze ohne Zähler-Wert und keine Lücken in der Zählerfolge haben will, möchte ich das ganze gerne per Transaktion lösen.

Warum nutzt du nicht Autoinc Felder... Was ist der Sinn daran, keine Lücken entstehen zu lassen.. Warum stört das?

Grund der Frage: Eine ID soll auf Ewigkeit eindeutig sein. Wenn Du einen Record löschst, ist er weg. Das rechtfertigt aber noch nicht, wieder einen neuen Datensatz mit gleicher ID anzulegen.

Stell Dir vor du hast eine Kundentabelle, und eine Verkaufstabelle, in der eine Spalte über eine ID auf den Kunden referiert. Löschst Du den Kunden, verweist die Rechnung ins Leere... An sich schon schlimm genug. Legst Du aber jetzt einen neuen Kunden mit der alten ID an, so verweist die Rechnung auf einen falschen Kunden, was noch schlimmer ist.

Fellmer Lloyd 18. Aug 2006 11:07

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
@mkinzler: Hier muss ich passen, da ich nicht weiss was eine Sequenz ist (Datenbank bezogen).

@Jelly: AutoInc ist nicht möglich, weil werte in dieser Spalte manchmal geändert werden müssen (Lange Geschichte und leider nicht zu ändern).
Mit den ID's habe ich mich evtl. falsch ausgedrückt: Ich will natürlich keinen neuen Datensatz mit gleicher ID (habe ich das so erklärt?).

Die ganze Datenstruktur inkl. Zähler habe ich nur zur veranschaulichung beschrieben, da ist noch mehr dahinter.
Eigentlich möchte ich nur wissen wie das ganze per Transaktion funktioniert. :)

Also wie die SQL Befehle lauten um das ganze Query entweder komplett (keine Fehler) oder gar nicht (irgend ein Fehler) auszuführen.

Jelly 18. Aug 2006 11:14

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Zitat:

Zitat von mkinzler
Unterstützt MSSQl keine Sequenzen?

Das nennt sich dort globale Variablen... Angesprochen werden die mit einem doppelten @, also z.B.

SQL-Code:
@@id

mkinzler 18. Aug 2006 11:16

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Zitat:

@mkinzler: Hier muss ich passen, da ich nicht weiss was eine Sequenz ist (Datenbank bezogen).
Sequenzen sind Teil des SQL2003-Standards. dabei handelt es sich um Tabellenunabhängige Variablen die in einer critical section erhöht werden können.

hoika 18. Aug 2006 11:22

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Hallo,

viell. hilft das hier ja eiter

http://www.devtrain.de/artikel_371.aspx

Heiko

Fellmer Lloyd 18. Aug 2006 13:57

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Danke für die Antworten.

@Hoika: Danke, der Link hat mir sehr weitergeholfen.
Ich die Anweisungen nun in einen TRY Block gepackt. Bei einem Fehler (CATCH Block) wird nun ein ROLLBACK ausgeführt.
SQL-Code:
BEGIN TRANSACTION InsertTest;

BEGIN TRY
  -- Anweisungen (Zähler erhöhen & INSERT)
  -- {...}

  COMMIT TRANSACTION InsertTest;
  SELECT 0 AS Result; -- 0 = Erfolgreich
END TRY

BEGIN CATCH
  ROLLBACK TRANSACTION InsertAccount;
  SELECT 1 AS Result; -- <>0 = Fehler
END CATCH
Gruss Fellmer

hoika 18. Aug 2006 16:12

Re: Transaktion (Zähler erhöhen & anschliessendes INSERT
 
Mein erster VB-Tip.

tratra

*Rotkäppchen aufmach*


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz