![]() |
Datenbank: Firebird • Version: 2.0 • Zugriff über: IBO
Trigger
Hallo ich habe folgenden Code im Trigger:
Delphi-Quellcode:
Bei if new.geburtsmonat_zahl = 1 then kommte ein Parsing error. Was ist hier falsch?
if (new.geburtsdatum > '') then
begin new.geburtstag = extract(day from new.geburtsdatum); new.geburtsmonat_zahl = extract(Month from new.geburtsdatum); if new.geburtsmonat_zahl = 1 then if new.geburtsmonat = 'Januar'; end |
AW: Trigger
Sicher, dass nicht stattdessen das sinnlose „if“ in der nachfolgenden Zeile moniert wird?
|
AW: Trigger
Hab mit Firebird noch nie was gemacht, aber ist es nicht wie z.b. in C, dass du == machen musst?
|
AW: Trigger
Auf jeden Fall kann es auch nicht schaden, den Ausdruck zu klammern
Code:
if (…) then
|
AW: Trigger
Danke
So funktioniert es:
Delphi-Quellcode:
if (new.geburtsdatum > '') then
begin new.geburtstag = extract(day from new.geburtsdatum); new.geburtsmonat_zahl = extract(Month from new.geburtsdatum); if (new.geburtsmonat_zahl = 1) then new.geburtsmonat = 'Januar'; end |
AW: Trigger
Leider immer noch ein Problem. Hier mal der Ganze Trigger.
Delphi-Quellcode:
Der Trigger lässt sich nicht kompilieren. Keine Ahnung warum. Vielleicht sieht jemand den Fehler.
as
declare variable Monat Integer; declare variable Tag Integer; begin if (new.ZAHLUNGSPFLICHTIG = 'J') then if (((new.ZAHLUNGSART is null) or (new.ZAHLUNGSART = '')) or ((new.ZAHLUNGSZEITPUNKT) is null or (new.ZAHLUNGSZEITPUNKT = ''))) then exception EXCP_INVALID; if (new.geburtsdatum > '') then begin Tag = extract(day from new.geburtsdatum); Monat = extract(Month from new.geburtsdatum); if (Monat = 1) then New.geburtsmonat = 'Januar'; if (Monat = 2) then new.geburtsmonat = 'Februar'; if (Monat = 3) then new.geburtsmonat = 'März'; if (Monat = 4) then new.geburtsmonat = 'Aprol'; if (Monat = 5) then new.geburtsmonat = 'Mai'; if (Monat = 6) then new.geburtsmonat = 'Juni'; if (Monat = 7) then new.geburtsmonat = 'Juli'; if (Monat = 8) then new.geburtsmonat = 'August'; if (Monat = 9) then new.geburtsmonat = 'September'; if (Monat =10) then new.geburtsmonat = 'Oktober'; if (Monat = 11) then new.geburtsmonat = 'November'; if (Monat = 12) then new.geburtsmonat = 'Dezember'; Old.geburtstag = Tag; Old.geburtsmonat_zahl = Monat; end end |
AW: Trigger
ist das richtig so, dass Du old ändern willst? Steht das überhaupt schreibbar zur Verfügung?
|
AW: Trigger
Ja stimmt ist natürlich falsch. Hab ich geändert nun lässt sich der Trigger kompilieren. Leider kann ich aber weder einen Daten Satz ändern noch neu anlegen. Muss glaub ich irgendwie mit den Variablen zu tun haben.
Hier muss der Fehler liegen. Tag = extract(day from new.geburtsdatum); Monat = extract(Month from new.geburtsdatum); Jahr = extract(year from new.geburtsdatum); aber was ist falsch? |
AW: Trigger
Hallo Walther,
auch wenn Firebird bei mir viele Jahre her ist... Aber deine 12 if then Statements solltest Du auch so schreiben können:
Code:
Macht das Ganze etwas übersichtlicher.
New.geburtsmonat = case
when Monat = 1 then 'Januar' when Monat = 2 then 'Februar' when Monat = 3 then 'März'' when Monat = 4 then 'April' when Monat = 5 then 'Mai' when Monat = 6 then 'Juni' when Monat = 7 then 'Juli' when Monat = 8 then 'August' when Monat = 9 then 'September' when Monat = 10 then 'Oktober' when Monat = 11 then 'November' when Monat = 12 then 'Dezember' end; |
AW: Trigger
Zitat:
Außerdem machst du noch ein extract auf das Jahr, was in deinem Code für den Trigger nicht enthalten ist. Ist der Code, den du uns zeigst vielleicht unvollständig und wie sehen daher gar nicht alle potentiellen Fehlerstellen? Bitte folgendes genau prüfen:
Code:
Läuft der Trigger vielleicht in die Exception?
if (((new.ZAHLUNGSART is null) or (new.ZAHLUNGSART = '')) or ((new.ZAHLUNGSZEITPUNKT) is null or (new.ZAHLUNGSZEITPUNKT = ''))) then
exception EXCP_INVALID; Abgesehen davon ist beim Zahlungszeitpunkt nicht richtig geklammert. Um es zu vereinfachen, kannst du die Prüfung wie folgt ändern:
Code:
Das sollte dann so aussehen:
(new.ZAHLUNGSART is null) or (new.ZAHLUNGSART = '')
-- wird zu: coalesce(new.ZAHLUNGSART, '') = '' -- und (new.ZAHLUNGSZEITPUNKT) is null or (new.ZAHLUNGSZEITPUNKT = '') -- wird zu: coalesce(new.ZAHLUNGSZEITPUNKT, '') = ''
Code:
Und bei der Gelegenheit noch Aprol in April ändern :wink:
if ((coalesce(new.ZAHLUNGSART, '') = '') or (coalesce(new.ZAHLUNGSZEITPUNKT, '') = '')) then
exception EXCP_INVALID; |
AW: Trigger
OK hier nochmals der ganze Trigger:
Delphi-Quellcode:
Ich befürchte das es mit dem Geburtsdatum zu tun hat. Die ist in der Datenbank ein Datumsfeld (Date).
as
declare variable Monat Integer; declare variable Tag Integer; declare variable Jahr Integer; begin if (new.ZAHLUNGSPFLICHTIG = 'J') then if (((new.ZAHLUNGSART is null) or (new.ZAHLUNGSART = '')) or ((new.ZAHLUNGSZEITPUNKT) is null or (new.ZAHLUNGSZEITPUNKT = ''))) then exception EXCP_INVALID; if (new.geburtsdatum > '') then begin Tag = extract(day from new.geburtsdatum); Monat = extract(Month from new.geburtsdatum); Jahr = extract(year from new.geburtsdatum); if (Monat = 1) then New.geburtsmonat = 'Januar'; if (Monat = 2) then new.geburtsmonat = 'Februar'; if (Monat = 3) then new.geburtsmonat = 'März'; if (Monat = 4) then new.geburtsmonat = 'April'; if (Monat = 5) then new.geburtsmonat = 'Mai'; if (Monat = 6) then new.geburtsmonat = 'Juni'; if (Monat = 7) then new.geburtsmonat = 'Juli'; if (Monat = 8) then new.geburtsmonat = 'August'; if (Monat = 9) then new.geburtsmonat = 'September'; if (Monat =10) then new.geburtsmonat = 'Oktober'; if (Monat = 11) then new.geburtsmonat = 'November'; if (Monat = 12) then new.geburtsmonat = 'Dezember'; new.geburtstag = Tag; new.geburtsmonat_zahl = Monat; new.geburtsjahr = Jahr; end end |
AW: Trigger
Falsche Position der Klammer
SQL-Code:
müsste
((new.ZAHLUNGSZEITPUNKT) is null or (new.ZAHLUNGSZEITPUNKT = ''))) then
SQL-Code:
lauten.
((new.ZAHLUNGSZEITPUNKT is null) or (new.ZAHLUNGSZEITPUNKT = ''))) then
|
AW: Trigger
Ist das wirklich Firebird 2? Aktuell ist Firebird 5, wobei der Umstieg nicht besonders schwierig ist.
Wenn da ein eigenes Programm mit der Datenbank arbeitet, ist es wesentlich einfacher die Delphi Datumsroutinen zu verwenden als so einen relativ komplizierten Trigger zu bauen. Auch braucht man 4 Felder in der Datenbank, wo eigentlich eines reicht, wovon 3 berechnete Werte speichern. Das hat wahrscheinlich geringen Einfluss auf Größe und Performance der Datenbank, ist aber unschön. Braucht man die Werte z.B. für Export von Daten, könnte man sie auch über eine Stored Procedure abfragen. |
AW: Trigger
Ich weiß nicht, ob man FB debuggen kann, aber falls nicht, würde ich aus dem Trigger erstmal eine User Defined Function oder Stored Procedure machen.
Mit entsprechenden Parametern und Rückgabewerten kann man dann prüfen, an welcher Stelle es hakt. Damit hättest du auch die Möglichkeit, dir einen Soll-Ist-Vergleich zu erstellen. |
AW: Trigger
debuggen kann man so was in ibexpert, aber das bringt nur wenig erkenntnisse wenn man grundlegende
vergleiche sinnlos codiert.
Code:
warum soll ein datum >'' sein?
if (new.geburtsdatum > '') then
entweder kommt da rechts auch ein datum rein oder du prüfst auf not null firebird liefert auch brauchbare fehler, in einigermaßen aktuellen firbeird versionen auch gleich mit zeilennummer (die o.a. zeile ist in meinem test genau zeile 12)
Code:
so funktioniert das
Overflow occurred during data type conversion.
conversion error from string "". At trigger 'TESTX_BU0' line: 12, col: 5. ---------------------------------------------- SQLCODE: -413 SQLSTATE: 22018 GDSCODE: 335544334
Code:
if (new.geburtsdatum > '1.1.1900') then
|
AW: Trigger
Danke an Holger Klemt, das war der entscheidende Tipp.
|
AW: Trigger
Zitat:
|
AW: Trigger
Zitat:
|
AW: Trigger
Zitat:
|
AW: Trigger
Zitat:
![]() Zitat:
Zitat:
|
AW: Trigger
Zitat:
Code:
ergebnis 45677
select current_date-cast('30.12.1899' as date) from rdb$database
die range ist dabei nicht das problem weil der wert ja auch negativ sein kann. auch das hier geht
Code:
ergebnis -693593
select cast('01.01.0001' as date)-cast('30.12.1899' as date) from rdb$database
Ich finde das verfahren sehr gut gelöst, weil die darstellung sprich umrechnung in tag/monat/jahr ob mit oder ohne schaltjahr unabhängig vom wert ist, der ja nur anzahl tage vor oder hinter 0 darstellt. ich kann mich aus grauer vorzeit noch daran erinnern, das mysql mit einem datum 30.2. nie probleme hatte, auch wenn das immer unsinn war. mag aber sein, das die das mittlerweile auch anders machen. und ergänzende infos: als timestamp ist das identisch nur mit nachkommastelle, d.h. mittags um 12 ist plus 0,5 usw. später kam dann auch noch die zeitzone mit in die daten. das die nicht negative jahre vor dem jahr 0 unterstützen kann ich nachvollziehen, das braucht auch nicht jede branche und bis zum enddatum im jahr 9999 haben wir noch circa 3mio tage verfügbar, das sollte für fast alle sinnvollen aufgaben auch reichen. Zumindest aus unserer heutigen sicht ;-) |
AW: Trigger
Zitat:
Code:
ergibt den 30.12.1899
select current_date-45677 from rdb$database
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz