i

Schlüssel erzeugen

Es ist lästig, bei der Eingabe eines neuen Schülers selbst einen künstlichen Primärschlüssel zu suchen, der ja eindeutig sein muss.
Das folgende Programm (hier zum Download) erzeugt automatisch die nächste freie Nummer für einen neuen Fahrschüler:

print("Neuanlage eines Fahrschülers")
print("============================")

neuName    =     input("Name   : ")
neuVorname =     input("Vorname: ")

# höchste Nummer finden
cursor = con.cursor()
SQLBefehl = 'SELECT MAX(SNR) FROM schueler'
cursor.execute(SQLBefehl)
row=cursor.fetchone()

neuSNR = int(row[0])+1


SQLBefehl = '''
   INSERT INTO schueler (SNR, Vorname, Name) 
        VALUES (%i,'%s','%s')
''' % (neuSNR, neuName,neuVorname)
cursor.execute(SQLBefehl)
# print(cursor._executed.decode('UTF-8')) # funktioniert nur mit MySQL
cursor.close()

Das Programm wird in den allermeisten Fällen funktionieren. Allerdings gibt es Probleme, wenn zwei oder mehrere Benutzer gleichzeitig einen Benutzer einfügen wollen:

Konkurrierende Zugriffe auf die Schülernummer[1]

Beide Benutzer lesen nacheinander die höchste vergebene Nummer aus und erhöhen diese um 1. Beim Einfügen verwenden damit beide die gleiche Nummer, was beim Benutzer mit dem späteren Commit zu einer Fehlermeldung führen muss.

Alternative in MySQL

MySQL (und auch andere Datenbanksysteme) bieten für dieses Problem der Schlüsselgenerierung eigene (und leider auch unterschiedliche Lösungen). Unter MySQL kann bei einem Attribut die Anweisung AUTO_INCREMENT ergänzt werden:

CREATE TABLE IF NOT EXISTS schueler (
  SNR          integer NOT NULL AUTO_INCREMENT,
  Vorname      varchar(30),
  Name         varchar(50),
  BevorzugtFNR integer,
  PRIMARY KEY (SNR)
)

Wird dann bei einem INSERT der Wert für SNR nicht definiert, dann erzeugt MySQL automatisch einen Wert (den maximal vorhandenen Wert +1).

SQLite verhält sich hier sehr "benutzerfreundlich" - und nicht im SQL-Standard:
Ist ein Attribut (wie hier die SNR) vom Typ integer und als Primärschlüssel markiert, so vergibt SQLite automatisch einen unbenutzten Wert für SNR, sofern die SNR im INSERT nicht angegeben wird.

Quellen

Suche

v
3.4.5.3
dev.inf-schule.de/datenbanksysteme/zugriff/dml/exkurs_schluessel
dev.inf-schule.de/3.4.5.3
dev.inf-schule.de/@/page/6ksxoX5mfe7WuPYE

Rückmeldung geben