Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem (https://www.delphipraxis.net/213723-neuer-primaerschluessel-kann-nicht-angelegt-werden-validation-error-null-problem.html)

BlueStarHH 15. Sep 2023 10:43

Datenbank: Firebird • Version: 3.x • Zugriff über: IBDAC

Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
Hi,

ich habe eine Tabelle, in der ich den vorhandenen Primärschlüssel löschen möchte und eine neue ID-Spalte zum Primärschlüssel machen möchte. Das mache ich so:

SQL-Code:
CREATE SEQUENCE GEN_KUNDEPREIS_ID; commit;
ALTER TABLE KUNDEPREIS DROP CONSTRAINT PK_KUNDEPREIS; commit;
ALTER TABLE KUNDEPREIS ADD ID INTEGER; commit;
Update KundePreis set ID = (select gen_id(GEN_KUNDEPREIS_ID, 1) from rdb$database); commit;
ALTER TABLE KUNDEPREIS ALTER ID SET NOT NULL; commit;
ALTER TABLE KUNDEPREIS ADD CONSTRAINT PK_KUNDEPREIS PRIMARY KEY (ID); commit; <--- Fehler hier!!!!
Dabei erscheint diese Fehlermeldung:

Zitat:

validation error for column ID, value "*** null ***"
Warum? Es können doch gar keine Datensätze mit null in der ID-Spalte exisiteren, da ich diese Spalte mit dem Generator fortlaufend auffülle. Schaue ich mit dem IBExpert in die Tabelle, sind nach dem Generator-Aufruf auch keine Datensätzt mit Null in der ID zu sehen. Aber tortzdem kann er den PK nicht erstellen. (Auch mit anderen Tabellen besteht das selbe Problem.)

BerndS 15. Sep 2023 11:10

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
Ich mache das immer in einer Anweisung.
Also in deinem Fall würde ich folgende Anweisung an den Server schicken:
Code:
ALTER TABLE KUNDEPREIS ADD ID INTEGER NOT NULL PRIMARY KEY;

BlueStarHH 15. Sep 2023 11:17

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
Zitat:

Zitat von BerndS (Beitrag 1526973)
Ich mache das immer in einer Anweisung.
Also in deinem Fall würde ich folgende Anweisung an den Server schicken:
Code:
ALTER TABLE KUNDEPREIS ADD ID INTEGER NOT NULL PRIMARY KEY;

Wie soll das funktionieren, wenn schon Daten in der Tabelle sind? Dann ist ist ID-Spalte ja Null und der PK kann nicht gesetzt werden.

IBExpert 15. Sep 2023 11:38

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
DDL und DML laufen in unterschiedlichen Transaktionskontexten. Bei vielen Metadatenänderungen
benutzen wir daher innerhalb von IBExpert einen reconnect befehl dafür, den es aber nicht
überall gibt.

mach mal vor deinem zweiten alter table block nach dem update/commit so ein reconnect
dann sollte das klappen wenn nicht andere auch auf der db sind

BerndS 15. Sep 2023 12:00

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
Zitat:

Wie soll das funktionieren, wenn schon Daten in der Tabelle sind? Dann ist ist ID-Spalte ja Null und der PK kann nicht gesetzt werden.
:oops: Da habe ich deinen 1. Beitrag nicht richtig gelesen und daher Mist geschrieben.

paule32.jk 15. Sep 2023 15:15

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
habe ich auch noch nicht gehört, das der PK null sein sollte.
So gut wie ALLE Datenbank-Systeme/Server initializieren den PK mit einer fortlaufenden
Nummer...

Felder die Null sind, sind solchem die gerade angelegt wurden, und es kein Dateneinschub
stattgefunden hat.
Eventuell FieldByName->AsString := ''; damit das Feld für String-Eingabe initzialisiert wird,
sofern das Datenfeld auch mit CHAR/VARCHAR/TEXT erstellt wurde.

Die Anzahl der COMMIT Anweisungen macht mir irgendwie sorgen - sollte da nicht ein Transaktionsblock
besser gedient haben ?
Manche SQL-Systeme/Server verstehen START TRANSACTION/BEGIN ... END/END TRANSACTION COMMIT.
Bin mir da jetzt nicht sicher, ob die Server Festplatte dadurch nicht besser geschütz wäre - für
Datenbankzugriffe - in einer modernen Welt mit DSL-Geschwindigkeiten....

BlueStarHH 15. Sep 2023 15:30

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
Zitat:

Zitat von IBExpert (Beitrag 1526976)
DDL und DML laufen in unterschiedlichen Transaktionskontexten. Bei vielen Metadatenänderungen
benutzen wir daher innerhalb von IBExpert einen reconnect befehl dafür, den es aber nicht
überall gibt.

mach mal vor deinem zweiten alter table block nach dem update/commit so ein reconnect
dann sollte das klappen wenn nicht andere auch auf der db sind

Danke für die Info. Wahrscheinlich wird es mit den Transaktionskontexten zu tun haben. Auf die Schnelle mal ein reconnect ins TIBScript eingebaut, aber es erscheint trotzdem die Fehlermeldung. Ich sehe auch gerade dass das TIBScript hat auch eine AutoDDL-Eigenschaft hat, die festlegt, ob für DDL-Statements eine eigene Transkation benutzt werden soll oder nicht. Aber egal ob true oder false, trotzdem die bekannte Fehlermeldung. Ich muss das ganze wohl aus meinem großen Projekt rauslösen und ein Mini-Demo zum nachvollziehen erstellen.

IBExpert 15. Sep 2023 16:23

AW: Neuer Primärschlüssel kann nicht angelegt werden: validation error / Null-Problem
 
besser nicht vermischen, was da wo passiert oder passieren sollte

Ein PK braucht bei fast allen datenbanken not null columns, auch bei Firebird
aber
Ein PK muss aber keineswegs überhaupt existieren noch aus nur einer numerischen ganzzahligen spalte bestehen, die das Datenbanksystem mit irgendwas füllen sollte

Daher sind irgendwelche Datenbanksysteme (welche auch immer das sind), die einen PK selber mit irgendwas selbstständig initialisieren, ohne das der SQL dazu die regel vorgibt, aus meiner sicht nur begrenzt relevant, wenn überhaupt existent.

Aber zum thema: DDL/DML Transaktionen:
Firebird kann ohne probleme im laufenden Betrieb während leute offenen Selects auf einer Tabelle mehrfach abfragen und dadurch eine bestimmte Struktur z.B. mit select * erwarten bedienen.
Ein Alter Table add column .... erzeugt ein neues Format (in rdb$formats zu finden), in der dann auch die neue spalte zu finden ist. erst bei neu geschriebenen Datensätze wird da aber bei insert oder update dieses format herangezogen und man kann was in diese spalte schreiben. In jeder Datensatzversion innerhalb der Datenpages ist auch die verwendete rdb$format version hinterlegt 8bit, daher gibt es da unten in ibexpert manchma den hinweis xxx versions left on table yyy). Pro tabelle kann es 255 formats geben, für weitere alter table muss man dann ggf backup/restore machen.

ich denke mal der Teil der Erklärung geht weit über das hinaus, was man sich so üblicherweise beim alter table add .... vorstellt, aber alte säcke wie ich kennen das auch noch von paradox oder dbase, bei denen eine strukturänderung dadurch gemacht wurd, das die komplette Tabelle in eine komplett neue Tabelle kopiert werden musste und das dauert ewig bei großen datenmengen, geschweige denn das man das mit offenen userconnections genau auf dieser Tabelle machen konnte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:35 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