[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Mar 2005
    Beiträge
    74

    GENERATED BY DEFAULT

    Folgendes Problem: Ich habe in einer SQL-Tabelle eine Spalte definiert als GENERATED BY DEFAULT um auch Werte für diese Spalte vorgeben zu können:

    Code:
    ID INTEGER GENERATED BY DEFAULT AS IDENTITY ( 
     START WITH 1 INCREMENT BY 1 
     NO MINVALUE NO MAXVALUE 
     NO CYCLE NO ORDER 
     NO CACHE )
    Wenn kein Wert vorgegeben wird, soll der DB-Manager automatisch einen Wert generieren.

    In der Beschreibung zu GENERATED BY DEFAULT steht folgendes:
    For an identity column or row change timestamp column, the database manager inserts a specified value but does not verify that it is a unique value for the column unless the identity column or row change timestamp column has a unique constraint or a unique index that solely specifies the identity column or row change timestamp column.
    Bei ensprechenden Constraint bin ich nun davon ausgegeben, das wenn eine bereits verwendete ID vom DB-Manager ermittelt wird, dieser automatische die nächst freie Id nimmt.
    Ein entsprechende Constraint ist in der Tabelle definiert:
    Code:
    CONSTRAINT constname PRIMARY KEY( ID )
    Die Anwendung bricht mir aber mit SQL0803 (Doppelter Schlüssel) weg, wenn keine ID im Insert angegeben ist und die vom DB-Manager ermittelte Id mit einer bereits manuell vorgegebenen Id übereinstimmt.

    Was mache ich falsch?

    Danke im Voraus!

  2. #2
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Hast du den Default-Parameter beim Insert angegeben??

    Code:
    Insert into YourTab (ID, irgendwas) values (default, 'wirklich irgendwas');
    lg Andreas

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.245
    Normalerweise muss man solche Felder beim Insert weglassen, damit SQL eben die Nummer automatisch vergeben kann.
    Gibt man sie selber vor, muss man diese auch selber verwalten (außer bei "default").

    Um das Ergebnis dieses Feldes dann zu erhalten da man es ggf. noch benötigt gibt es den:

    select IdField from final table
    (insert into .....)
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  4. #4
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Wenn du die Spalte weg lässt und nicht mit DEFAULT angibst, schreibt die DB NULL (oder versucht es zumindest). Deshalb muss bei einem Insert auch immer die Spalte mit DEFAULT angegeben werden.

    Ich hab mich früher mal mit diesem Thema beschäftigt und bin zum Schluss gekommen:
    *) Entweder lässt man die Nr. IMMER vom System generieren (dann braucht man die Spalte auch nicht mit DEFAULT angeben). Dafür muss nur ein entsprechender Parameter beim CREATE/ALTER TABLE angegeben werden
    *) Oder die Anwendung schreibt die Nr.

    Eine Mischung von Beiden geht auf dauer nicht gut!

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.245
    Nun ja, doch ein wenig inkonsistent.
    Entweder ich habe ein automatisches Feld, dann muss ich es weglassen oder ich habe keins.

    Diese "Halbautomatic", nur mit "Default" gibts einen Wert, ohne wirds NULL, kann man ja kaum einem erklären.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  6. #6
    Registriert seit
    Mar 2005
    Beiträge
    74
    Das mit Angabe von DEFAULT und ansonsten wird NULL reingeschrieben ist nicht richtig!!

    Wenn Id weggelassen wird, wird ein Wert erstellt, ansonsten würde SQL0801 nicht hochkommen.

    Die Mischung zwischen selbstgeneriert und automatisch generiert ist notwendig, weil eine alte Tabelle abgelöst wird, bei der die alten IDs noch bekannt sind und in alten Programmen benutzt werden. Bei neueren Sätzen ist die Id für den Endbenutzer nicht mehr wichtig.

  7. #7
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    ... Works as designed!
    Primary und Unique Key Constraints und Unique Indices/logische Dateien, sorgen lediglich dafür, dass kein doppelter Satz erzeugt wird, in dem beim Schreiben eine entsprechende Abbruchmeldung ausgegeben wird.

    Der Grund für dieses Verhalten liegt darin, dass für die Ids einfach die nächsten Nummern bereitgestellt werden, aus Performance-Gründen jedoch nicht geprüft wird, ob ein Satz mit der entsprechenden Id bereits vorhanden ist. Dies erfolgt erst beim Schreiben.

    Warum setzt Du nicht einfach den aktuellen Wert der Id höher als der Maximal-Wert, der von der alten Datei kommen kann?

    Code:
    Alter Table YourSchema/YourTable
       Alter Column YourId Restart With 100000;
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  8. #8
    Registriert seit
    Mar 2005
    Beiträge
    74
    Die neue Datei wird in der alten Anwendung noch benutzt und hier ist der Schlüssel 3stellig, wobei 999 schon belegt wurde.

    Werde mir was anderes überlegen...

    Vielen Dank!

Similar Threads

  1. dynamisches sql mit group by
    By n_sman in forum NEWSboard Programmierung
    Antworten: 11
    Letzter Beitrag: 09-07-12, 14:30
  2. SQl: select * From(select ...) as Res group By
    By oulbrich in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 12-01-12, 12:58
  3. NOT NULL WITH DEFAULT
    By deni87991 in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 04-08-06, 10:32
  4. Embedded SQL - Datenbankoptionen in VARPG
    By woki in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 13-04-04, 12:09
  5. SQL default library, wo bei XE1 V4R5
    By holly in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 08-04-04, 10:27

Tags for this Thread

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •