Kann ich gleichzeitig einen Wert ändern und auslesen (SQL)?

3 Antworten

Oh je! - Das 'ID' Problem ist doch ein absoluter Klassiker.

Ich verstehe dass dich das Problem beschäftigt, und ich weiß ehrlich gesagt auch gar nicht ob das schon jemand komplett gelöst hat. Jedoch habe ich mich mit dem Thema genauso auseinander gesetzt wie du, daher glaube ich genau zu verstehen was dein Ziel ist.

Du möchtest in der ID Spalte keinen Autowert vom SQL-Server vergeben lassen? Ich habe diverse Vermutungen, aber ich würde mich freuen wenn du mir das bestätigen könntest, oder mir einen Grund dafür nennen könntest.

Das Prinzip was du hier versuchst, ist eine Mischung aus dem Prinzip einer TAN-Tabelle und der MAX(ID) Variante.  (Zwei unterschiedliche Ansätze).

Du hast mit deiner aktuellen Variante ein Problem, nämlich: Willst du so bei anderen Tabellen vorgehen, benötigst du immer eine Content-Spalte.  Der Datentyp von Content und ID wird unterschiedlich sein. Daher erstelle doch dafür eine Tabelle, in der Tabellenname deiner Zieltabelle steht, sowie die zuletzt vergebene ID.

Ich weiß, das löst noch nicht dein Problem. Sondern macht es nur 'sauberer'. Du hast nämlich nun immer noch das Problem, dass es dadurch noch nicht wirklich Mehrbenutzer-fähig ist. - Was das betrifft, hätte ich noch folgenden Ansatz: Transaktionen:

Bitte verzeih wenn ich einen Mist erzähle, eigentlich ist die Syntax in MySQL und MSSQL in vielen Dingen gleich und ich bin nicht ganz so fit in MySQL.

In MSSQL habe ich die Möglichkeit dafür eine Procedure zu bauen: Ein komplexeres SQL-Statement dass ich in eine Funktion packen kann, die ich später simpel aufrufen kann. 

In dieser Funktion benötigst du eine Transaktion, die zunächst den Wert der TAN-Tabelle Abfrägt, um eins nach oben zählt und wieder in die Tabelle zurück schreibt und am Ende der Funktion dem Anwender die ID übermittelt.

Ohne Stored Procedure könnte das so aussehen:

DECLARE @ID int;

BEGIN TRANSACTION
SELECT @ID=TableID FROM MyTanTable WHERE TableName = 'table_name'

SET @ID = @ID+1;
UPDATE MyTanTable SET TableID=@ID WHERE TableName = 'table_name'

COMMIT TRANSACTION

INSERT INTO table_name(ID, Content) SELECT @ID, 'mein neuer inhalt'

Aus der Praxis noch folgender Hinweis: Du hast ein kleines aber feines Problem, dem du mit einem Workaround begegnen musst: Auch wenn du eine Transaktion startest, löst Das Select-Statement noch keine Datensatz-Sperre aus. wodurch ein Paralleler-Zugriff auf die Transaktion möglich ist. - Daher wirst du noch ein weiteres Feld in der TAN-Tabelle benötigen, das nennst du einfach: Lock als smallint.

Direkt nach der Zeile mit BEGIN TRANSACTION setzt du die Sperre via:

UPDATE MyTabTable SET Lock=-1 WHERE TableName = 'table_name'

und setzt beim zweiten UPDATE-Statement, in der du die neue ID zurück schreibst das Feld wieder auf 0.

Ich verstehe ehrlich gesagt nicht was du da genau machst :-)

Du kannst den primary-key ID doch auf auto-increment stellen. Dann brauchst du dich um deine ID nicht kümmern, er inkrementiert dann den Index automatisch.

Bei einem INSERT liefert er dir die ID normalerweise zurück, so dass du diesen Wert wieder lesen kannst. Wenn du ohnehin schon etwas einfügst, kennst du den Inhalt bereits. --> Brauchst dir diese Mühe grundsätzlich nicht machen.


KnusperPudding  17.01.2016, 15:36

Ein Grund weshalb man ein TAN-Verfahren gegenüber Autoincrement verwendet, wäre, wenn man in der Applikation eine komplette Relation abbilden möchte, bevor man diese Speichert, z.B.:

Rechnung: ID 1

Position ID 1, RechnungsReferenz auf RechnungID.

safur  17.01.2016, 16:45
@KnusperPudding

Ich weiß schon was ein TAN-Verfahren ist. Mir kam die Anfrage seitens des Fragestellers aber eher .. forschend rüber. :-)

KnusperPudding  24.01.2016, 19:19
@safur

Kein Problem. - Ich finde das Thema im allgemeinen schwierig. Und ich nehme an, der Fragesteller wusste auch einfach noch nicht den entsprechenden Begriff für =)

Das kommt mir alles ziemlich sinnlos und unüberlegt vor. Warum nimmst du nicht einfach die ID als Primärschlüssel und setzt diese Spalte auf autoincrement. Dann musst du nix an den IDs ändern.