AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken FireDAC : Trigger geht nicht
Thema durchsuchen
Ansicht
Themen-Optionen

FireDAC : Trigger geht nicht

Ein Thema von Hansa · begonnen am 4. Sep 2015 · letzter Beitrag vom 7. Sep 2015
Antwort Antwort
Seite 3 von 5     123 45      
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#21

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 00:00
Sicher, dass die 101 noch nicht da ist?

Ausgehend von den Quelltextfragmenten, kann es die 101 nur einmal geben.
Es gibt sie nicht mal einmal. Das 1. Insert scheitert schon. Siehe Fehlermeldung. Ich versuche also, einen nicht vorhandenen Datensatz mit eingebautem unique Key in die DB einmalig einzufügen und das 1-mal und dann so was. Das i sollte schon hochgezählt werden, aber es besteht nur noch Folgendes : i := 0; Danach ist alles auskommentiert, was eigentlich geplant war. Jetzt kommt noch der Witz : Habe das Unique-Key-Feld Nicht-unique gemacht und der Fehler ist nicht weg ! Ok, Datenbank fast leer gemacht und immer noch dasselbe. Näcgster Ansatz wäre dann die DB an sich. Gibt ConnectionName da vielleicht falsche Namen zurück ? Die lasse ich mir nämlich vorsichtshalber anzeigen. Und sie beziehen sich auch auf die zu bearbeitende DB.

Wäre ja naheliegend, dass ich die falsche benutze. Sehe das aber nicht so.
Gruß
Hansa
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#22

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 00:35
Moment, nochmal zum Mitschreiben. Du machst also nur noch das:
Delphi-Quellcode:
i := 0;
DM.DS.Insert;
DM.DS.FieldByName('NR').AsInteger := i + 100;
DM.DS.FieldByName('BEZ').AsInteger := i;
DM.DS.Post;
und das scheitert beim ersten Datensatz in eine leere Tabelle mit einer Schlüsselverletzung im Feld Nr in einer Tabelle, die für das Feld Nr keinen eindeutigen Schlüssel hat?

1. Drop Table und neumachen.
2. Erneut probieren, Fehler weg?
3. Wenn nein, neue Datenbank machen, nur diese Tabelle und den Trigger und erneut probieren.
4. Fehler weiter da? Rechner ausschalten und morgen erneut probieren Nein, ehrlich gesagt keine Ahnung.

Gibt es irgendeinen Cache, der Daten vorhält..., so dass das Programm irgend etwas "aus der Vergangenheit" sehen könnte, was in der Realität nicht mehr existiert?
Aber dann dürfte ja die Datenbank nicht meckern. Gibts da 'nen Clone von, auf den Du noch (irrtümlich) zugreifst?

Entwicklungsumgebung mal zugemacht?
Datenbank neu gestartet?
Neues, leeres Projekt mit nur dem Datenbankzugriff und dem Insert in diese Tabelle (nicht per Copy&Paste aus dem "alten" Projekt übernehmen, wer weiß, was jetzt da nicht stimmt)?
Kenne FireDac nicht (mein Delphi ist zu alt), gibt es denn da die Möglichkeit etwas so stark zu "verkonfigurieren", dass daraus ein derartiges Problem resultieren könnte?

Glaube nicht, dass ich hierzu noch irgendwas halbwegs sinnvolles schreiben könnte
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#23

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 01:24
Hansa, ich seh da nur das eine Problem aus deinem Eingangsposting:

Delphi-Quellcode:
    DM.DS.Insert;
    DM.DS.FieldByName('NR').AsInteger := i + 100;
    DM.DS.FieldByName('BEZ').AsInteger := i;
    DM.DS.Post;
    if i mod 1000 = 0 then begin
mem1.Lines.Add(IntToStr (i));
      DM.Trans.Commit;
      DM.Trans.StartTransaction;
    end;
Du versuchst, ein Feld, das durch eine Trigger-Generator-Kombination von der DB beim Insert automatisch befüllt wird, im vom Clienten aus zuzuweisen. Also ent oder weder ...

In solchen Fällen erhalte ich ebenfalls eine Fehlermeldung, das kann nicht funktionieren. Du legst ja auch den Wert des PrimaryKeys nicht im Client fest, wenn du dafür in der DB ebenfalls einen Trigger hast, der bereits reagiert, bevor die vom Client gesendeten Daten eingetragen werden. Laß also einfach die Zuweisung an das Feld NR im Client weg und du hast dieses Problem nicht mehr.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#24

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 06:17
Hallo,
das Autoinc-Feld ist aber ID, nicht NR ...


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.387 Beiträge
 
Delphi 12 Athens
 
#25

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 06:36
Hallo Hansa,

mache doch einfach mal ein
Code:
FireDacQuery.SQL.Text:= 'insert into TABLE (NR,BEZ) values (:nr,:be)'; // vor der Schleife -> nur einmal zuweisen. Macht bei den heutigen Rechnern kaum einen Unterschied.
FireDacQuery.ParamByName('nr').AsInteger:= i + 100; //die Parametersyntax könnte ggf. abweichen
FireDacQuery.ParamByName('be').AsInteger:= i;
FireDacQuery.ExecSQL;
Wie schon gefragt. (Antwort vieleicht überlesen) Wird der Generator erhöht wenn dein Fehler kommt?

Geändert von haentschman ( 5. Sep 2015 um 06:38 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#26

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 08:23
Hallo Hansa,

mache doch einfach mal ein
Code:
FireDacQuery.SQL.Text:= 'insert into TABLE (NR,BEZ) values (:nr,:be)'; // vor der Schleife -> nur einmal zuweisen. Macht bei den heutigen Rechnern kaum einen Unterschied.
FireDacQuery.ParamByName('nr').AsInteger:= i + 100; //die Parametersyntax könnte ggf. abweichen
FireDacQuery.ParamByName('be').AsInteger:= i;
FireDacQuery.ExecSQL;
Wie schon gefragt. (Antwort vieleicht überlesen) Wird der Generator erhöht wenn dein Fehler kommt?
Hansa schrieb weiter oben, dass der Trigger funktioniert.

Aber ließe sich der obige Code nicht noch erweitern, in dem man immer eher sowas macht:
Delphi-Quellcode:
sSQL := 'insert into TABLE (NR,BEZ) values (%d,%s);';
DM.Query.SQL.Clear;
DM.Trans.StartTransaction;
for i := 1 to n do begin
  DM.Query.SQL.Add(Format(sSQL,[i + 100,QuotedStr(i)]));
  if i Mod 1000 = 0 then begin
    DM.Query.ExecSQL;
    DM.Trans.Commit;
    mem1.Lines.Add(IntToStr(i));
    DM.Query.SQL.Clear;
    DM.Trans.StartTransaction;
  end;
end;
Hier werden dann halt immer 1000 Inserts an einem Stück an die Datenbank gegeben und von ihr verarbeitet, statt satzweise. Hab' sowas in de Art vor Jahren mal bei 'ner SQL-Server-Datenbank gemacht, dass hat bei der zu verarbeitenden Datenmenge etliche Stunden Zeitersparnis gebracht.
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#27

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 09:29
Hier werden dann halt immer 1000 Inserts an einem Stück an die Datenbank gegeben und von ihr verarbeitet, statt satzweise. Hab' sowas in de Art vor Jahren mal bei 'ner SQL-Server-Datenbank gemacht, dass hat bei der zu verarbeitenden Datenmenge etliche Stunden Zeitersparnis gebracht.
Diesen Ansatz gibt es in FireDAC nativ und je nach DBMS kann FireDAC gegenüber eine Lösung mit Format() optimieren. Nennt sich Array DML.
(http://docwiki.embarcadero.com/RADSt...ehls_(FireDAC))
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#28

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 09:33
@Daniel
Das ist doch eine absolut elegante Lösung.
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#29

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 09:49
mal zurück zur eigentlichen Problematik

Datasets, die für Delphi und Firebird entwickelt wurden, wie zum Beispiel IBObjects, haben Properties, mit denen man den verbundenen Generator festlegen kann. Das heisst dann bei IBO z.B. KeyGeneratorLink o.ä.

Da man in Firebird selbst entscheiden kann, welcher Generator pro Tabelle benutzt wird, ist dieser Weg sehr praktisch, denn bei mir gibt es für alle Tabellen immer nur einen Generator, aus dem alle ID Werte geholt werden.

Nun kommen aber mehr generalisierte Komponenten wie Firedac nicht mit jeder unterstützten Plattform zu 100% klar. Mein Tip: Verliert euch nicht in der Abhängigkeit zu einer Komponente. Wie oben schon erwähnt bekommt Firebird noch gar nicht mit, das es einen Insert geben sollte, wenn auf Ebene der Delphi Komponente Bedingungen noch gar nicht erfüllt sind. Man könnte das als Mangel der FireDac Komponenten im Zusammenspiel mit Firebird betrachten oder einfach mal in den Dataset Events nach OnNewRecord suchen.

Wenn Ihr im OnNewRecord Ereignis dann ein SQL startet "select gen_id(genid,1) from rdb$database" und den Rückgabewert in euer Primärschlüsselfeld übertragt, werdet Ihr feststellen, das es gar nicht so schwer ist, selbst die Kontrolle über solche Vorgänge zu haben. Wenn Ihr ein Generator pro Tabelle habt, könntet ihr das auch dynamisch machen, weil im Event ja der Sender(also das Dataset) kommt und das ja hoffentlich properties hat, aus denen sich der Tabellenname ergibt.

Und wenn Ihr das Event nicht für jedes Dataset manuell neu setzen wollt, könnt Ihr mit sehr wenig Aufwand auch ein global benutzbares Event dafür im Datenmodul generieren und das ggf. jedem Dataset in der components List im OnCreate zuweisen. Oder noch viel cleverer, einfach eine Ableitung der benutzten Dataset Klasse machen, in dem das automatisch passiert.

Wichtig: Nur weil Firebird und FireDAC vorne vier gleiche Buchstaben haben, ist FireDAC keineswegs die erste Wahl für Firebird und Delphi.
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung

Geändert von IBExpert ( 5. Sep 2015 um 10:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
671 Beiträge
 
FreePascal / Lazarus
 
#30

AW: FireDAC : Trigger geht nicht

  Alt 5. Sep 2015, 09:59
Hier werden dann halt immer 1000 Inserts an einem Stück an die Datenbank gegeben und von ihr verarbeitet, statt satzweise. Hab' sowas in de Art vor Jahren mal bei 'ner SQL-Server-Datenbank gemacht, dass hat bei der zu verarbeitenden Datenmenge etliche Stunden Zeitersparnis gebracht.
Wenn es um maximum Speed mit Firebird geht, sammel die Daten als Insert Befehle zeilenweise mit Semikolon getrennt z.B. lokal in einer TStringlist (aber nicht mehr als 255 Befehle und nicht länger als 32kb) und übergebe die Werte direkt im Text (keine parameter benutzen). Danach dann noch eine Zeile mit "execute block as begin " davor und ein "end" an Ende dahinter und schick das in eine Query.sql property und führ das aus mit Query.execSql.

Damit sind auch aus Delphi heraus bis zu 10000 Inserts pro Sekunde in die Firebird DB machbar.
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:45 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