Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Verständnisfrage Autoinc bei Firebird (https://www.delphipraxis.net/157040-verstaendnisfrage-autoinc-bei-firebird.html)

zeras 26. Dez 2010 12:33

Datenbank: Firebird • Version: 2.5 • Zugriff über: IB

Verständnisfrage Autoinc bei Firebird
 
Ich nutze folgenden SQL Code zum Erstellen einer Tabelle. Das geht soweit
Code:
CREATE TABLE "LIZENZ"
(
  "ID"         INTEGER NOT NULL,
  "Firma"     VARCHAR(80),
  "Notes"      BLOB SUB_TYPE TEXT SEGMENT SIZE 80,
  FOREIGN KEY      ("Programm_ID")
  REFERENCES    PROGRAMME("Programm_ID")
);
Dazu noch einen Trigger

Code:
CREATE TRIGGER "AUTOINC" FOR "LIZENZ"
ACTIVE BEFORE INSERT POSITION 0
as
begin
 new.id = gen_id( autoinc, 1 );
end
Wenn ich nun über ein DBGrid und DBNavigator neue Daten einfügen will, dann trage ich doch bei ID nichts ein, da das Firebird für mich erledigt. Das dachte ich mir jedenfalls. Wenn ich nun neue Daten eintragen und dann sichern will, kommt die Meldung, dass das Feld ID einen Wert haben muss.
Was mache ich falsch?

FBrust 26. Dez 2010 12:52

AW: Verständnisfrage Autoinc bei Firebird
 
Hallo,

da fehlt wohl der sog. Generator.

Wenn Du z. b. mit IBExpert oder ähnlichen Tools eine Tabelle erstellst, siehst Du sehr schön die dabei erzeugten Skripte.

Gruß
Frank

ThomasBab 26. Dez 2010 12:53

AW: Verständnisfrage Autoinc bei Firebird
 
Hallo!

Nur ganz kurz, es ist ja Weihnachten.


1. ID würde ich als bigint definieren, könnte sonst knapp werden.

2. Hier ein Beispiel aus einer Tabelle in einer Datenbank von mir, ohne weiteren Kommentar:

Code:
/******************************************************************************/
/*                 Generated by IBExpert 26.12.2010 13:51:15                  */
/******************************************************************************/

/******************************************************************************/
/*        Following SET SQL DIALECT is just for the Database Comparer        */
/******************************************************************************/
SET SQL DIALECT 3;



/******************************************************************************/
/*                                   Tables                                  */
/******************************************************************************/


CREATE GENERATOR ID;

CREATE TABLE USERLIST (
    ID       BIGINT NOT NULL,
    ANGELEGT DATUMUHRZEIT NOT NULL /* DATUMUHRZEIT = TIMESTAMP */,
    BENUTZER VCHAR30 NOT NULL COLLATE DE_DE /* VCHAR30 = VARCHAR(30) */,
    SOUNDEX  CHAR(6) COLLATE DE_DE
);




/******************************************************************************/
/*                                Primary Keys                               */
/******************************************************************************/

ALTER TABLE USERLIST ADD CONSTRAINT PK_USERLIST PRIMARY KEY (ID);


/******************************************************************************/
/*                                  Indices                                  */
/******************************************************************************/

CREATE INDEX USERLIST_IDX1 ON USERLIST (SOUNDEX);
CREATE INDEX USERLIST_IDX2 ON USERLIST (BENUTZER);


/******************************************************************************/
/*                                  Triggers                                 */
/******************************************************************************/


SET TERM ^ ;



/******************************************************************************/
/*                            Triggers for tables                            */
/******************************************************************************/



/* Trigger: USERLIST_BIU0 */
CREATE OR ALTER TRIGGER USERLIST_BIU0 FOR USERLIST
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
begin
if (new.id is null) then
    new.id = gen_id(id, 1);
    if (new.angelegt is null) then
    new.angelegt = current_timestamp;
    new.soundex = f_soundex(f_upper(new.benutzer));
end
^


SET TERM ; ^
Gruß
Thomas

alzaimar 26. Dez 2010 13:02

AW: Verständnisfrage Autoinc bei Firebird
 
Zitat:

Zitat von ThomasBab (Beitrag 1070496)
1. ID würde ich als bigint definieren, könnte sonst knapp werden.

Nun ja. Mir haben 2 Mrd immer gereicht. Was speicherst Du denn? Alle Bakterien dieser Welt?

Bei dem Fehler könnte es auch sein, das Delphi bzw. der Provider selbst meckert. Es handelt sich bei ID um ein Pflichtfeld.

Abhilfe: Schreibe aus der Anwendung heraus irgendeinen Murks in das ID Feld (z.B. 0) oder deklariere das AutoInc-Feld als 'Optional'. Ich glaube, das heißt "Required"...

borwin 26. Dez 2010 13:08

AW: Verständnisfrage Autoinc bei Firebird
 
Hallo,

Dein Problem liegt nicht in der Datenbank. Sowie Du es schilders ist dort alles i.o. Der Trigger könnte nocht optimiert werden .siehe
hierzu die Antwort von Thomas.
Dein Problem liegt bei Delphi, denke ich. Du hast die Felder im Datatset aus der Tabelle generieren lassen. Dabei wurde erkannt, dass das Feld ID NOT NULL ist.
Jetzt wird schon vor dem Speichern in die DB die Bedingung geprüft. Schau mal in den Propertys von dem Feld nach. Ich glaube Required muss auf False stehen.

Schöne Weihnachten

BORWIN

zeras 26. Dez 2010 13:16

AW: Verständnisfrage Autoinc bei Firebird
 
Zitat:

Zitat von borwin (Beitrag 1070498)
Hallo,

Jetzt wird schon vor dem Speichern in die DB die Bedingung geprüft. Schau mal in den Propertys von dem Feld nach. Ich glaube Required muss auf False stehen.

BORWIN

Ja, das wars. Vielen Dank.
Mal sehen, was ich noch am Trigger ändern kann. Werde die Daten übendrüber mal testen. Dann kommt vielleicht der Timestamp gleich mit.

ThomasBab 26. Dez 2010 13:22

AW: Verständnisfrage Autoinc bei Firebird
 
Zitat:

Zitat von alzaimar (Beitrag 1070497)
Zitat:

Zitat von ThomasBab (Beitrag 1070496)
1. ID würde ich als bigint definieren, könnte sonst knapp werden.

Nun ja. Mir haben 2 Mrd immer gereicht. Was speicherst Du denn? Alle Bakterien dieser Welt?

Hallo!

Naja, 2 Mrd könnte schon knapp werden, denn ich nehme einen Generator für alle IDs in allen Tabellen der Datenbank (bin ja faul).

Und da reichen mir 2 Mrd auf keinen Fall (z.B. meine Flugdatenbank
- www.sparflugplan.com
, die regelmäßige Updates der Flugdaten erfährt), da eine einmal vergebene ID ja "verbrannt" ist, d.h. nicht mehr vergeben wird.

Außerdem tut es nicht weh, wenn ich für die IDs einen größeren Datentyp wähle, wie gesagt, ich bin faul.

Gruß
Thomas


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz