Anmelden

View Full Version : Probleme mit Identity Column in Table



Seiten : [1] 2 3

Tonazzo
09-03-16, 07:36
Hallo zusammen,

Ich habe eine Datei (TABLE) mit einem Identity Column.
Sporadisch kommt es vor, dass dieses Feld scheinbar nicht vom System hochgezählt wird.
Bei einem Insert erscheint somit die Meldung "Doppelter Schlüssel vorhanden".
ADNR wird hochgezählt - habe ich beim Debuggen bereits geprüft.

Hatte jemand schon mal dieses Phänomen bzw. eine Idee voran es liegen könnte.
Entsprechender Code folgt unten, da beim Hochladen eines Anhanges ein Fehler auftrat.

Vielen Dank im Voraus...

=====================
Referenzdatei
=====================
CREATE TABLE MYLIB/REFDATP (

SID INT NOT NULL GENERATED ALWAYS AS IDENTITY
(START WITH 1
INCREMENT BY 1
CYCLE
CACHE 10
MAXVALUE 999999999),

ADNR NUMERIC(8, 0) NOT NULL WITH DEFAULT ,
LDKZ CHAR(3) CCSID 273 NOT NULL WITH DEFAULT ,
STR CHAR(35) CCSID 273 NOT NULL WITH DEFAULT ,
LDKZ CHAR(3) CCSID 273 NOT NULL WITH DEFAULT ,
ORT CHAR(35) CCSID 273 NOT NULL WITH DEFAULT );

=====================
Adressen
=====================
CREATE TABLE MYLIB/ADRESSP AS
(SELECT SID AS AD0SID,
ADNR AS AD0ADNR,
STR AS AD0STR,
STR AS AD0STR2,
LDKZ AS AD0LDKZ,
ORT AS AD0ORT,
ORT AS AD0ORT2
FROM MYLIB/REFDATP)
WITH NO DATA
INCLUDING IDENTITY COLUMN ATTRIBUTES
RCDFMT ADRESSR;

LABEL ON TABLE MYLIB/ADRESSP IS 'Adressenstamm' ;

ALTER TABLE MYLIB/ADRESSP
ADD CONSTRAINT ADRESSP_PK PRIMARY KEY (AD0SID);

ALTER TABLE MYLIB/ADRESSP
ADD CONSTRAINT ADRESSP_UK UNIQUE (AD0ADNR);

=====================
Code im Zugriffsprogramm
=====================
exec sql
INSERT INTO ADRESSP
VALUES(DEFAULT,
:n_AD0ADNR,
:n_AD0STR,
:n_AD0STR2,
:n_AD0LDKZ,
:n_AD0ORT,
:n_AD0ORT2);

Fuerchau
09-03-16, 08:09
Das Problem mit solchen Spalten ist, dass diese nur beim Insert belegt werden.
Es wird aber nicht verhindert, dass beim Update der Wert verändert wird.
Dies lässt sich nur mit einem Before-Insert-Trigger prüfen, wer der Verursacher beim Ändern ist.

B.Hauser
09-03-16, 08:31
Evt. hilft aber auch schon, wenn der Cache von 10 erhöht wird. U.U. kann das System bei Massen-Inserts die neuen Werte in Cache nicht schnell genug nachladen.

Sofern sichergestellt ist, dass die ID nicht durch einen manuellen Eingriff geändert wurde und dadurch diese Duplicate erzeugt wurden, und außerdem sichergestellt ist, dass die ID nicht manuell neu aufgesetzt wurde oder durch CYCLE wieder von vorne angefangen wird, würde ich einen CALL bei IBM eröffnen.

Birgitta

Tonazzo
09-03-16, 08:49
Gibt es die Möglichkeit im Vorfeld zusehen welche ID das System beim nächsten INSERT vergeben wird?
Ich kann ja nicht unbedingt davon ausgehen, dass es die letzte in der Datei vorhanden ID + 1 ist, falls
diese manuell neu aufgesetzt wurde..

camouflage
09-03-16, 08:53
Kurze Frage (bin ja kein SQL-Held):
Gibt es evtl. einen Key-Ueberlauf?
Den Max-Value hast du bei 999999999 definiert, dein Keyfeld ist jedoch nur 8 stellig.

Tonazzo
09-03-16, 09:01
Der Max-Value bezieht sich auf die ID nicht auf die ADNR.
Die Datei hat zurzeit 25690 Sätze - entsprechend ist auch die ADNR.
Also kein Key-Ueberlauf.

andreaspr@aon.at
09-03-16, 09:41
Da hier mit GENERATED ALWAYS gearbeitet wird, kann die ID nicht manuell geändert werden.
Weder bei einem INSERT noch einem UPDATE.
Ich würde auch, wie Birgitta schon vorgeschlagen hat, einen CALL bei der IBM eröffnen.

B.Hauser
09-03-16, 09:55
So wie Du die Identity definiert hast bezieht sich der MaxValue NICHT auf ADNR, sondern auf die ID.

Schau Dir die Spalten-Definition doch mal über die Catalog-View SYSCOLUMNS an.

Die nächste Identity-Nr kannst Du aus der Catalog-View SYSPARTITIONSTAT (Spalte NEXT_IDENTITY_VALUE) ermitteln.

Birgitta

Tonazzo
09-03-16, 10:14
@B.Hauser
Genau das habe ich ja um 10:01 an @camouflage geschrieben (Thema ADRNR)!
Wo finde ich den Catalog-View SYSPARTITIONSTAT? Wir haben V5R4 auf der Maschine?

@andreaspr@aon.at
Eine Zurücksetzung/Änderung mit dem OPSERV ist schon möglich!

Fuerchau
09-03-16, 11:23
Bei V5R4 wird es keine Fehlerbehebung mehr geben, da nützt ein IBM-Call auch nichts mehr.
Da ist halt raten angesagt.
"Generate Always" bedeutet nur beim Insert, dass ein Wert vergeben wird, egal ob ich NULL angebe, das Feld nicht verwende oder eine bestimmten Wert eintrage. Wäre ja fatal, wenn ein Update den Wert ständig verändern würde.
Dies verhindert nicht den (versehentlichen) Update des Wertes.

Auch könnte das Zurücksetzen des Wertes zu doppelten Sätzen führen. Eine Überlauf bei 2^31 Werten halte ich eher für unwarscheinlich.