Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird Generator/Trigger für Autoinc (Verständnis_Problem) (https://www.delphipraxis.net/129416-firebird-generator-trigger-fuer-autoinc-verstaendnis_problem.html)

Mithrandir 28. Apr 2009 15:49

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Zitat:

Zitat von mkinzler
Wegen fehlendem Commit sind die Tabellen bei der Anlage der Trigger noch nicht sichtbar

Ähä.. Commit? Also das, was die ZeosLib unter ExecSQL versteht, oder? Meine DoQuery-Funktion liest sich so:

Delphi-Quellcode:
procedure TORPDataBase.DoQuery(QueryStr: String);
begin
  fQuery := TZQuery.Create(nil);
  try
    with fQuery do
    begin
      Connection := fConnection;
      SQL.Add(QueryStr);
      ExecSQL;
    end;
  finally
    fQuery.Free;
  end;
end;
Der erste Aufruf von FireBirdAutoInc funktioniert und auch später in der DB wird die Spalte "ID" artig inkrementiert, wenn das INSERT INTO Statement so aussieht:

SQL-Code:
INSERT INTO NODES (NODE_ID, LAT, LON, TAGS) VALUES (:node_id, :lat, :lon, :tags) RETURNING "ID"
Nur beim zweiten Aufruf scheitert es leider...

mkinzler 28. Apr 2009 15:50

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
FireBird arbeitet mit Transaktion. Tabellen/Trigger sind Einträge in Systemtabellen, welche erst nach Commit der Transkation sichtbar werden.

Mithrandir 28. Apr 2009 16:13

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
*Grübeldigrübel*

Das heißt, vermutlich wäre hier ein fConnection.Connect mit anschließendem fConnection.Disconnect vor dem FireBirdAutoInc-Block angebracht, oder? Wenn dem so ist, dann habe ich immer noch ein Problem. Beim Programmstart prüfe ich, ob die Datenbank bereits existiert. Wenn nicht, soll sie angelegt werden.

Delphi-Quellcode:
function TORPDatabase.Connect(DBUser, DBPassword, DBHostName: string): boolean;
begin
  with fConnection do
  begin
    Protocol := 'firebird-2.0';
    ReadOnly := false;
    User     := DBUser;
    Password := Password;
    Database := fCompleteDBPath;
    HostName := DBHostName;
    if not FileExists(fCompleteDBPath) then
      CreateEmptyDB;
    Connect;
    Result := Connected;
  end;
end;

procedure TORPDataBase.CreateEmptyDB;
begin
  with fConnection do
  begin
    Properties.Add('CreateNewDatabase=CREATE DATABASE ' + QuotedStr(Database)
      + ' USER ' + QuotedStr(User) + ' PASSWORD ' +
      QuotedStr(Password) + ' PAGE_SIZE 4096');
  end;
  FillDB;
end;

procedure TORPDataBase.FillDB;
begin
  DoQuery('CREATE TABLE MEMBERS (ID BIGINT NOT NULL, MEMBER_ID BIGINT,"TYPE" VARCHAR(255), REF BIGINT,"ROLE" VARCHAR(255));');
  DoQuery('CREATE TABLE NODES (ID BIGINT NOT NULL, NODE_ID BIGINT, LAT FLOAT, LON FLOAT, TAGS VARCHAR(20000));');
  DoQuery('CREATE TABLE RELATIONS (ID BIGINT NOT NULL, RELATION_ID BIGINT, MEMBERS VARCHAR(5000), TAGS VARCHAR(5000));');
  DoQuery('CREATE TABLE TAGS (ID BIGINT NOT NULL, "KEY" VARCHAR(255), "VALUE" VARCHAR(255));');
  DoQuery('CREATE TABLE WAYS (ID BIGINT NOT NULL, WAY_ID BIGINT, NODES VARCHAR(5000), TAGS VARCHAR(5000));');

  fConnection.Connect;
  fConnection.Disconnect;


  FireBirdAutoInc(fConnection,'NODES','ID');
  FireBirdAutoInc(fConnection,'TAGS','ID');
end;
Wenn die Datenbank nicht existiert, dann wird zuerst CreateEmptyDB() und dann FillDB() aufgerufen. Springt die Funktion wieder zurück zu Connect() in TORPDatabase.Connect(), dann erhalten ich folgende Meldung:

Code:
---------------------------
saxxmltest
---------------------------
SQL Error: I/O error for file "G:\Dokumente und Einstellungen\Ich\Anwendungsdaten\OpenRoutePlanner\DB\ORP_MAIN.fdb" database or file exists. Error Code: -902. Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements The SQL: CREATE DATABASE 'G:\Dokumente und Einstellungen\Ich\Anwendungsdaten\OpenRoutePlanner\DB\ORP_MAIN.fdb' USER 'SYSADMIN' PASSWORD '' PAGE_SIZE 4096;
---------------------------
OK  
---------------------------
Als hätte er das CREATE DATABASE Statement noch nicht ausgeführt.... :gruebel:

Satty67 28. Apr 2009 17:02

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Der Fehler tritt bereits bei CREATE DATABASE auf... alles danach ist erst mal noch nicht interessant.
Also beim Anlegen der Datei 'G:\Dokumente und Einstellungen\Ich\Anwendungsdaten\OpenRoutePlanner \DB\ORP_MAIN.fdb'

Passwort hast Du selbst ausgeklammert? masterkey bei embbed Firebird.

Evtl. die Datenbankdatei mal in einem anderen Ordner anlegen.

€: Edit...steht ja da... Du versuchst eine neue Datenbank anzulegen, aber die Datenbankdatei existiert bereits. Wenn die Datenbank ORP_MAIN.fdb noch leer ist, dann löschen.

mkinzler 28. Apr 2009 17:08

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Das Passwort ist bei embedded egal, da ja nur der Benutzernamen ausgewertet wird

Satty67 28. Apr 2009 17:14

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Kein Passwort nötig, Ok :drunken:

Also denke ist einfach, dass Du beim Testen versuchst, vorhandene Elemente nochmal anzulegen. Die erste Fehlermeldung könnte bedeuten, dass du den Trigger identisch nochmal anlegen willst. Die letzte, dass Du die bereits vorhandene Datenbank nochmal erzeugen willst.

Also falls noch beim Testen, die Datenbank löschen und nochmal alles neu anlegen lassen. Für später wäre eine Abfrage nötig... Datenbank existiert bereits, Trigger existiert bereits.

Mithrandir 28. Apr 2009 17:20

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Äh, ja, die Fehlermeldung habe ich ja auch gelesen. Ich lösche die Datenbank, und dann erscheint der Fehler. Und ich weiß nicht, wo ich zum zweiten Mal eine Datenbank erstelle. Oder habe ich gerade was falsch verstanden? :gruebel:

Satty67 28. Apr 2009 17:34

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
also nach "properties.add('CreateNew..." müsste doch gleich ein Connect folgen?

Du kannst die Tabellen nicht in der erzeugten, aber nicht geöffneten Datenbank anlegen. Also zConnection.Connect vor FillDB.

Dein Ablauf:
CreateEmptyDB; -> FillDB
Connect;
Delphi-Quellcode:
if not FileExists(fCompleteDBPath) then
begin
  CreateEmptyDB;
  Connect;
  FillDB;
end else
  Connect;
...und FillDB aus CreateEmptyDB rausnehmen.

Mithrandir 28. Apr 2009 18:44

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Zitat:

Zitat von Satty67
Du kannst die Tabellen nicht in der erzeugten, aber nicht geöffneten Datenbank anlegen. Also zConnection.Connect vor FillDB.

Doch, das ging vorher einwandfrei. Die Tabellen waren da, und ich konnte sie mit Daten füllen. Erst als der Autoinc hinzukommen sollte, kamen die Probleme. MySQL gefällt mir in dem Zusammenhang besser...

Ich habe deinen Vorschlag umgesetzt, er hilft jedoch nicht alleine. Denn ich bekomme so immer noch die Meldung:

Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt saxxmltest.exe ist eine Exception der Klasse EZSQLException mit der Meldung 'SQL Error: unsuccessful metadata update DEFINE TRIGGER failed attempt to store duplicate value (visible to active transactions) in unique index "RDB$INDEX_8". Error Code: -607. This operation is not defined for system tables. The SQL: CREATE TRIGGER AUTOINC_TRG for TAGS
active before insert position 0
as
begin
  new.ID = gen_id( TAGS_AUTOINC, 1 );
end
; ' aufgetreten.
---------------------------
Anhalten  Fortsetzen  Hilfe  
---------------------------
Ich musste einen kleinen Teil deiner Prozedur anpassen:

Delphi-Quellcode:
SQL.Add('CREATE TRIGGER AUTOINC_TRG for '+Table);
wurde zu

Delphi-Quellcode:
SQL.Add('CREATE TRIGGER '+Table+'AUTOINC_TRG for '+Table);
So funktioniert es einwandfrei.

P.S.: Danke für den Hinweis auf "Password". Hatte im Eifer des Gefechts glatt das "DB" vergessen... :oops:

DeddyH 28. Apr 2009 18:53

Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
 
Das ist eben der Unterschied, ob man DB-globales Autoinc oder eines je Tabelle verwenden möchte. Wenn Letzteres, müssen alle DB-Objekte (also auch Trigger und Generatoren) eindeutig benannt sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.
Seite 2 von 4     12 34      

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