Oracle SQL: Wie man ein Feld liest und erhöht

8

Ich überarbeite das Datenimportverfahren für eine Unternehmensanwendung und stoße auf ein Snippet, das ich gerne eine bessere Lösung finden würde. Beim Importieren von Daten müssen wir eine eindeutige Entität für jeden Datensatz erstellen, und in einem Feld befindet sich ein Zähler, mit dem diese ID sequenziell zugewiesen werden kann. Sie lesen das Feld, um die nächste freie ID zu erhalten, und erhöhen sie anschließend, um sich auf das nächste Mal vorzubereiten.

Im Moment geschieht dies in zwei Schritten in der ursprünglichen App, geschrieben in "C":

%Vor%

Offensichtlich gibt es hier eine Race Condition, wenn mehrere Prozesse dasselbe tun.

Bearbeiten: Wichtiger Zusatz: Ich kann die Datenbank / Felddefinition nicht berühren, dies schließt eine Sequenz aus.

Wir schreiben in Perl um, und ich würde das Gleiche tun, aber besser. Eine atomare Lösung wäre schön. Leider sind meine SQL-Kenntnisse begrenzt, daher wende ich mich der kollektiven Weisheit zu: -)

    
markus_b 08.01.2010, 17:14
quelle

4 Antworten

9

In diesem speziellen Fall ist eine Sequenz die richtige Lösung wie erwähnt. Wenn Sie jedoch in einer zukünftigen Situation sowohl etwas aktualisieren als auch einen Wert in derselben Anweisung zurückgeben müssen, können Sie die Klausel RETURNING verwenden:

%Vor%

Wenn der aufrufende Code PL / SQL ist, ersetzen Sie den? mit einer lokalen PL / SQL-Variable; Andernfalls können Sie es als Ausgabeparameter in Ihrem Programm binden.

Bearbeiten: Da Sie Perl erwähnt haben, sollte so etwas funktionieren (ungetestet):

%Vor%

Siehe DBI .

    
Dan 08.01.2010, 17:27
quelle
4

Warum nicht eine Sequenz verwenden?

Erstellen Sie die Sequenz einmal mit dem gewünschten START WITH-Wert:

%Vor%

Dann können Sie diese Anweisung in Ihrem Anwendungscode zur Laufzeit verwenden, um den nächsten Wert zu erhalten:

%Vor%

Aktualisierung: Die Verwendung einer Sequenz wäre die bevorzugte Methode, aber da Sie die Datenbank nicht ändern können, stimme ich zu, dass die Verwendung von RETURNING für Ihre Situation funktionieren sollte:

%Vor%     
wweicker 08.01.2010 17:18
quelle
2

Verwenden Sie SELECT FOR UPDATE-Anweisung. Es garantiert sich gegenseitig ausschließende Rechte an dem Datensatz:

"SELECT FÜR UPDATE;

    
Ender 08.01.2010 17:31
quelle
0

Eine Sequenz wird die Aufgabe erledigen, sehen Sie sich z. Oracle-Sequenzen

    
Steve De Caux 08.01.2010 17:18
quelle

Tags und Links