2 Stimmen

Vermeidung eines zweistufigen Einfügens in SQL

Sagen wir, ich habe eine Tabelle wie folgt definiert:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKey varchar(255) NOT NULL,
)

CompoundKey ist ein String mit dem Primärschlüssel P_Id am Ende verkettet, wie z.B. Foo00000001, was von "Foo" + 00000001 kommt. Derzeit erfolgen Eintragsinsertionen in diese Tabelle in 2 Schritten.

  1. Fügen Sie einen Dummy-Datensatz mit einem Platzhalterstring für CompoundKey ein.
  2. Aktualisieren Sie den CompoundKey mit der Spalte mit dem generierten Verbundschlüssel.

Ich suche nach einer Möglichkeit, das 2. Update vollständig zu vermeiden und alles mit einem einzigen Insert-Statement zu erledigen. Ist das möglich? Ich benutze MS SQL Server 2005.

p.s. Ich stimme zu, dass dies nicht das sinnvollste Schema der Welt ist, und dieses Schema wird refaktorisiert (und ordnungsgemäß normalisiert), aber ich kann im Moment keine Änderungen am Schema vornehmen.

5voto

Chris J Punkte 29515

Ihr könntet eine berechnete Spalte verwenden; ändere das Schema in:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKeyPrefix varchar(255) NOT NULL,
CompoundKey AS CompoundKeyPrefix + CAST(P_Id AS VARCHAR(10))
)

Auf diese Weise wird Ihnen SQL Server automatisch Ihren Verbundschlüssel in einer neuen Spalte geben und automatisch für Sie pflegen. Sie können auch das PERSIST Schlüsselwort für berechnete Spalten in Betracht ziehen, was SQL Server dazu veranlasst, den Wert in den Datendateien zu materialisieren, anstatt ihn jedes Mal neu zu berechnen. Sie können auch bei Bedarf einen Index gegen die Spalte hinzufügen.

1voto

Gustav Barkefors Punkte 4826

Ein Auslöser würde dies leicht erreichen

1voto

Matthew Punkte 10056

Dies ist einfach nicht möglich.
Die "nächste ID" existiert nicht und kann daher nicht gelesen werden, um das UPDATE zu erfüllen, bis die Zeile eingefügt ist.

Wenn Sie Ihre Autonummern von woanders beziehen würden, könnten Sie dies tun, aber ich glaube nicht, dass dies eine gute Antwort auf Ihre Frage ist.

Auch wenn Sie Trigger verwenden möchten, wird ein UPDATE ausgeführt, auch wenn Sie es nicht manuell ausführen. Sie können die Bevölkerung des CompoundKey verschleiern, aber am Ende des Tages wird es trotzdem ein UPDATE sein.

Ich denke, Ihr sicherster Einsatz ist es sicherzustellen, dass das UPDATE in der gleichen Transaktion wie das INSERT erfolgt oder einen Trigger verwendet. Aber rein akademisch betrachtet wird dennoch ein UPDATE durchgeführt.

1voto

Tomas Punkte 54613

Zwei Dinge:

1) Wenn Sie am Ende zwei Einfügungen verwenden, müssen Sie Transaktion verwenden! Andernfalls können andere Prozesse die Datenbank in einem inkonsistenten Zustand sehen (d.h. Datensatz ohne CompoundKey).

2) Ich würde davon absehen, versuchen, die Id am Ende von CompoundKey in Transaktion, Trigger usw. einzufügen. Es ist viel sauberer, es am Ausgang zu tun, wenn Sie es benötigen, z.B. in Abfragen (select concat(CompoundKey, Id) as CompoundKeyId ...). Wenn Sie es als Fremdschlüssel in anderen Tabellen benötigen, verwenden Sie einfach das Paar (CompoundKey, Id).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X