Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   AutoIncrement mit FireBird (https://www.delphipraxis.net/207627-autoincrement-mit-firebird.html)

Marco Steinebach 15. Apr 2021 19:33

Datenbank: FireBird • Version: 3.0 • Zugriff über: IBDAC

AutoIncrement mit FireBird
 
Hallo zusammen,
Ich möchte gern in FB eine Tabelle erstellen, bei der das Feld "ID", welches auch zur eindeutigen Identifikation dient, bei jedem Insert automatisch hochgezählt wird.
Ich hab das Ganze zwar in Delphi gelöst, aber es muss doch, um Himmelswillen, auch irgendwie in der Datenbank zu verankern sein???
Ich hab schon viel über Generatoren und co gelesen, aber ich kapiere nicht, wo die hin müssen, und, tja, eigentlich kapiere ich das ganze Zeug nicht.
Kann mir da bitte mal jemand helfen?
Also ich träume von
Code:
CREATE TABLE 'TEST' (ID NOT NULL PRIMARY KEY AUTO_InCREMENT'
...
Sprich, wenn ich dann ein Insert oder Append absätze, brauche ich mich um die ID nicht mehr kümmern.
Und nu? ;-)

Für eure Antworten bedanke ich mich schonmal ganz herzlich.
Wandogau

TurboMagic 15. Apr 2021 19:45

AW: AutoIncrement mit FireBird
 
Ja, du brauchst einen Generator für sowas.
Was benutzt du denn um die DB zu verwalten?
IBExpert?
Dort gibt's glaube ich einen Baumknoten dafür.

Marco Steinebach 15. Apr 2021 19:49

AW: AutoIncrement mit FireBird
 
*lächel, bis jetzt nix. ;-)
Ein schlichtes
[code]
CREATE DATABASE TEST
{/code]
und das war's, bis jetzt. ;-)
Können solche Generatoren via SQL angelegt werden, oder wie?
Und wo kommt dann deren Aufruf hin?
Ich würde, furchtbar gern, alles, was angelegt werden muss mit meinem Programm selbst erledigen.

Herzlich grüßt
Wandogau

juergen 15. Apr 2021 20:26

AW: AutoIncrement mit FireBird
 
Es gibt einige Beispiel hier in der DP für einen Generator.
Vllt hilf dir das hier schon weiter => https://www.delphipraxis.net/1355130-post13.html

Delphi.Narium 15. Apr 2021 20:31

AW: AutoIncrement mit FireBird
 
Das erste Suchergebnis meiner Suchmaschine liefert für "firebird autoincrement" passende Statements mit ausführlicher Erläuterung.

How to create an autoincrement column?

Olli73 15. Apr 2021 22:08

AW: AutoIncrement mit FireBird
 
Bei Firebird 3 kann man sich das mit dem Generator und dem Trigger automatisieren lassen:

https://stackoverflow.com/questions/...ebird-database

haentschman 16. Apr 2021 06:32

AW: AutoIncrement mit FireBird
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin...:P
Zitat:

*lächel, bis jetzt nix.
...dann wird es aber Zeit. https://dbeaver.io/
Zitat:

Ich würde, furchtbar gern, alles, was angelegt werden muss mit meinem Programm selbst erledigen.
-1 :? Halte ich für schlecht. Früher habe ich auch so gedacht. Aber...DB Admistration ist Sache des DB Tools. :zwinker:
Begründung:
1. DB Sicherung und Wiederherstellung. Wenn du eine "ältere" DB wiederherstellen mußt, dann müßtest du das Programm laufen lassen um wieder den gleichen Meta Stand zu haben.
2. Du kannst keine Differenzscripte erstellen
3. Die DB sollte ihre "Version" kennen um dann Differenzscripte auszuführen zu können. (Tabelle "_Version" o.ä.)
4. Übersicht über die Änderungen (siehe Bild)

Beispiel:
Du hast eine DB mit Version 500 als Datensicherung. Die aktuelle DB hat aber 502...dann läßt du die Scripte für 501 und 502 nacheinader ausführen...fertsch. :zwinker:
Code:
Zitat:

Können solche Generatoren via SQL angelegt werden, oder wie?
ja...wie schon gesagt. :wink:
Zitat:

Und wo kommt dann deren Aufruf hin?
Ausführung des SQL mit den entspechenden Anweisungen

IBExpert 16. Apr 2021 07:56

AW: AutoIncrement mit FireBird
 
es gibt durchaus Kunden, die so was erfolgreich machen und in Ihrer Exe jeden Versionstand der db
einfach mit verteilen.

Ich mach das nicht, weil bei mir eine exe auch unterschiedliche Datenbankstände
bedienen kann, aber bei wem das Projekt immer eine 1zu1 Beziehung zwischen Datenbank und exe hat, der
kann in seiner exe ja einfach alle db sql definitionen durchnummerieren und in der db dann einfach
speichern, welcher Befehlsummer in dieser db zuletzt ausgeführt wurde und wenn eine neue exe kommt,
dann alle sql befehle auf dieser db ausführt, die noch erforderlich sind, um den neuesten Datenbankstand
zu erzeugen.

Wenn du sehen willst, welche Befehle gebraucht werden, um eine komplette firebird datenbank anzulegen, lade
dir zum Beispiel ibexpert auch als personal herunter und schau da in die db1_30.sql datei an, die dort für die
demo db mit kopiert wird ( da ist fast alles drin, was man in fb30 machen kann).

Deine Aufgabe wäre dann nur noch, das Script in Teile aufzuteilen, die deine Komponenten dann step by step
ausführen können und die dann entsprechend der o.a. Liste in deine exe aufzunehmen und die jeweils ausgeführte
dann als datenbankstand in der db zu speichern, damit beim nächsten Start der exe das nicht noch mal passiert.
Ob du die sql Befehle dann jeweils einfach als String konstanten mit passender benennung reinkompilierst
oder einfach als externe Textdatei zur exe auslieferst bleibt dir überlassen (es kann aber durchaus
komplexer werden als du auf den ersten blick denkst, weil wenn du ein objekt änder willst, das
von anderen benutzt wird, musst du ggf erst mal alle abhängigen objekte ändern oder sogar löschen
und ggf programmierst du dann deinen eigenen ibexpert nach, der so was sowieso schon kann.

auf der seite ddl siehst du in ibexpert auch alle befehle, die erforderlich sind, um das jeweilige
Datenbankobjekt zu erzeugen, das sieht dann zB so aus



Code:
/******************************************************************************/
/****              Generated by IBExpert 16.04.2021 08:46:47               ****/
/******************************************************************************/

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



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


CREATE GENERATOR ID;

CREATE TABLE ORDERS (
    ID          NUMERIC(18,0) NOT NULL,
    ORDERDATE   DATE NOT NULL,
    CUSTOMER_ID NUMERIC(18,0),
    NETAMOUNT   NUMERIC(12,2) NOT NULL,
    TAX         NUMERIC(12,2) NOT NULL,
    TOTALAMOUNT NUMERIC(12,2) NOT NULL
);



/******************************************************************************/
/****                             Primary keys                            ****/
/******************************************************************************/

ALTER TABLE ORDERS ADD CONSTRAINT PK_ORDERS PRIMARY KEY (ID);


/******************************************************************************/
/****                             Foreign keys                            ****/
/******************************************************************************/

ALTER TABLE ORDERS ADD CONSTRAINT FK_CUSTOMERID_1 FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMER (ID) ON DELETE CASCADE;


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

CREATE DESCENDING INDEX ORDERS_IDX1 ON ORDERS (ORDERDATE);


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



SET TERM ^ ;



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



/* Trigger: ORDERS_BI0 */
CREATE OR ALTER TRIGGER ORDERS_BI0 FOR ORDERS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
    if (new.id is null) then
    new.id = gen_id(id, 1);
END
^
SET TERM ; ^



/******************************************************************************/
/****                              Privileges                             ****/
/******************************************************************************/

Marco Steinebach 17. Apr 2021 20:06

AW: AutoIncrement mit FireBird
 
Hallo zusammen,
Erstmal ganz herzlichen Dank an alle für die Antworten. Meine Güte, ;-), ich glaube, ich muss mal meine Suchmaschine reparieren, die Links, die bei euch gleich oben standen, hat google mir nicht ausgespuckt - oder es war schon zu spät nachts.
Jedenfalls hab ich's jetzt verstanden. ;-)

Aber trotzdem nochmal eine blöde Frage:
Ich hab noch nicht wirklich verstanden, warum ich die DB nicht mit meinem Programm erstellen soll, gut, wenn ich gleich eine DB mit ausliefere, die toll ist, wird mein Quell-Code natürlich entsprechend kleiner, weil die ganzen Befehle da nicht drin sind, soweit so klar.
Mein Kunde hat also Version 1.5 meines Programms, und version 1.5 der passenden Datenbank.
Wo kommt die überhaupt hin, eine Tabelle für sowas?
Jetzt gibt es die Version 1.6.
Dafür müsste, die Datenbank 1.5 des Kunden, einige Änderungen machen, die aber, so sagt ihr, nicht mein Programm macht...
Sondern wer?
Also auf deutsch, V1.5 hat bei den Adressen noch keinen Spitznamen, die V1.6 schon.
Ich hätte jetzt einfach in mein Programm ein Alter Table gemacht, falls es die Spalte "spitzname" nicht gibt.
Wie macht ihr das?

Ich bin echt gespannt und grüße herzlich
Wandogau

IBExpert 18. Apr 2021 08:34

AW: AutoIncrement mit FireBird
 
da spricht generell nichts dagegen, aber was machst du wenn es im netzwerk mehrere User gibt? Die haben aus welchen Gründen auch immer verschiedene Versionsstände der exe.
soll deine exe dann einfach mal versuchen, das Feld anzulegen, auch wenn es schon existiert?
Probematischer wird es schon wenn es eine Tabelle zB mit allen Felder schon gibt, du aber warum auch immer einen Datentyp für ein Feld ändern willst ...

Wenn netzwerk und verschiedene exe bei dir gar kein Problem ist, dann kannst du das auch ignorieren, aber die Architektur am Anfang
hat schon so manchen Programmierer später fluchen lassen, als die Anwendung komplexer wurde, die Ansprüche der Anwender höher wurden und man auf einmal mehrere Kunden dafür hatte ....

Das deine exe bei Bedarf einfach alter table auf die bestehende Datenbank macht ist bei einer nicht im Netzwerk eingesetzen Datenbank selten ein Problem, im Netzwerk kann aber schon
ein eigentlich simpler neuer Index bei falscher Transaktionseinstellung problematisch sein, weil ein unique mit parallelen Inserts nicht so banal zu handeln ist (Firebird kann das,
aber ob du dann weisst, wie man das mit Firebird macht, ohne einen Datenbankshutdown zu machen, wirst du ggf später erkennen ....)

Und deine Frage ist keineswegs blöd, so wie du das verstaden hast, kannst du das ohne Einschränkung machen. Solange wir nicht wissen, welches Einsatzszenario deine Software hat,
werden viele von uns sicherlich Lösungen für Probleme schildern, die du ggf gar nichts haben wirst. Vielleicht wirst du dich aber auch früher, als du denkst, ärgern, das du da
den simplen weg gegangen bist.

TurboMagic 18. Apr 2021 09:02

AW: AutoIncrement mit FireBird
 
Zitat:

Zitat von Marco Steinebach (Beitrag 1487317)
Hallo zusammen,
Erstmal ganz herzlichen Dank an alle für die Antworten. Meine Güte, ;-), ich glaube, ich muss mal meine Suchmaschine reparieren, die Links, die bei euch gleich oben standen, hat google mir nicht ausgespuckt - oder es war schon zu spät nachts.
Jedenfalls hab ich's jetzt verstanden. ;-)

Aber trotzdem nochmal eine blöde Frage:
Ich hab noch nicht wirklich verstanden, warum ich die DB nicht mit meinem Programm erstellen soll, gut, wenn ich gleich eine DB mit ausliefere, die toll ist, wird mein Quell-Code natürlich entsprechend kleiner, weil die ganzen Befehle da nicht drin sind, soweit so klar.
Mein Kunde hat also Version 1.5 meines Programms, und version 1.5 der passenden Datenbank.
Wo kommt die überhaupt hin, eine Tabelle für sowas?
Jetzt gibt es die Version 1.6.
Dafür müsste, die Datenbank 1.5 des Kunden, einige Änderungen machen, die aber, so sagt ihr, nicht mein Programm macht...
Sondern wer?
Also auf deutsch, V1.5 hat bei den Adressen noch keinen Spitznamen, die V1.6 schon.
Ich hätte jetzt einfach in mein Programm ein Alter Table gemacht, falls es die Spalte "spitzname" nicht gibt.
Wie macht ihr das?

Ich bin echt gespannt und grüße herzlich
Wandogau

In meinem Fall nutzt jede Installation des Programms eine lokale DB,
weil viele die Daten in der DB zentral nicht wirklich sinnvoll sind und die Anwendung
auch ohne Netzwerkverbindung laufen muss.

Bei einem Update bringt der Installer eine neue DB Datei mit, die aber nicht so heißt wie
die produktiv benutzte. Mittels einem selber geschiebenen Sync Programm werden dann die Daten
aus der alten Datei in die neue kopiert und dann die neue Datei benutzt.

Das Sync Programm kann auch ggf. nötige Anpassung an Daten vornehmen, dazu gibt's in der
DB Datei eine eindeutige Versionskennung die dann ggf. den entsprechenden Vorgang triggert.

Grüße

TurboMagic

Neumann 18. Apr 2021 09:30

AW: AutoIncrement mit FireBird
 
Das kann man machen, neue Datenbank mit den "Alten" Daten füllen und dann die neue verwenden. Ist aber wesentlich aufwendiger als die Bestehende zu ändern. Fehler sind natürlich auch möglich, etwa wenn man vergisst die Tabelle X zu füllen usw. .

Einmal ist wohl kein Problem, aber was ist wenn der Benutzer 4 Updates auslässt und gleich von 1.5 auf 2.0 geht?

Ich würde es nicht so machen. Wir lassen bei jeder Versionsänderung die ganze Datenbank prüfen und alle Tabellen, Proceduren, Trigger usw. wenn nötig anpassen. Dauert manchmal etwas und kann auch teilweise fehlschlagen, wenn z.B. kein exklusiver Zugriff auf die Datenbank gegeben ist. Ist aber sonst recht sicher und man kann den Vorgang auch mehrmals durchführen wenn es nicht gleich klappt.

Marco Steinebach 15. Jul 2021 06:49

AW: AutoIncrement mit FireBird
 
Hallo zusammen,
Ich hab mich damit jetzt mal beschäftigt, und gleich noch ein Problem, oder eine Frage:
Code:
create table objects (
  id integer generated by default as identity primary key,
  name varchar(15)
);
Als ich meine Id noch selbst gefüllt habe, konnte ich einfach sagen:
Code:
insert into objects values (17, 'Test');
Die Id-Spalte füllt er jetzt selber.
Klar nun kann ich schreiben:
Code:
insert into objects (name) values ('Test');
Das funktioniert auch, aber mach das mal mit, sagen wir, über 20 Spalten... ;-)
Gibt es eine Möglichkeit beim Insert die ganze Bennennung der Spalten wegzulassen, aber so, dass er die Id selbst ausfüllt. Also sowas wie:
Code:
insert into objects values ({übergeh_die_Spalte},'Test');
Wenn ich ALLE Spalten beim Insert angeben muss, nützt mich das ganze schöne Auto-Increment nix.

Herzlich grüßt
Moo

Olli73 15. Jul 2021 07:08

AW: AutoIncrement mit FireBird
 
Gib als Wert NULL an.

himitsu 15. Jul 2021 08:34

AW: AutoIncrement mit FireBird
 
Nein, denn "NULL" heißt "schreib NULL in das Feld" und der Generator wird garnicht verwendet.


Es gibt einige DBMS, da kann man "DEFAULT" in INSERT-Statements benutzen.

Ansonsten werden Default- oder AutoInc-Definitionen nur dann verwendet, wenn das Feld eben nicht im INSERT-Statement drin steht.

SQL-Code:
INSERT INTO objects (name) VALUES ('Test');
INSERT INTO objects (id, name) VALUES (DEFAULT, 'Test');

INSERT INTO objects (name)
VALUES
  ('Test1'),
  ('Test2'),
  ('Test3'),
  ('Test4');

Zitat:

SQL-Code:
insert into objects values (17, 'Test');

Sowas macht man eh nicht, also ohne die Feld-Definitionen, denn das knallt schnell mal, wenn die Felder in der DB nicht der "erwarteten" Reihenfolge entsprechen, oder gar mehr Felder vorhanden sind.
Passiert z.B. gern mal bei Updates/Upgrades, wenn man über die Jahre die DB-Struktur anpasst, und Felder hinzufügt/entfernt/umbenennt/........

Marco Steinebach 15. Jul 2021 08:57

AW: AutoIncrement mit FireBird
 
Huhu Himitsu,
Gut, ;-), dann schreib ich's doch um - 'grummel!
Herzlichen Dank!


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