AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi SELECT-Statement innerhalb eines Triggers
Thema durchsuchen
Ansicht
Themen-Optionen

SELECT-Statement innerhalb eines Triggers

Ein Thema von EnORItZ · begonnen am 28. Sep 2006 · letzter Beitrag vom 29. Sep 2006
Antwort Antwort
EnORItZ

Registriert seit: 8. Sep 2003
11 Beiträge
 
#1

SELECT-Statement innerhalb eines Triggers

  Alt 28. Sep 2006, 20:42
Datenbank: Firebird • Version: 1.5 • Zugriff über: IB-Controls
Hallo Leute.

Ich versuche gerade in meiner Rechnungsdaten-Tabelle doppelte eingaben eines Artikels zu vermeiden.

Die Tabelle sieht quasi so aus:
SQL-Code:
create table Rechnungen(
   RechnungsID   Integer,
   KundenID   Integer,
   Datum      Date
);

create table RechnungsDaten(
   RechnungsID   Integer,
   AusleihID   Integer
);
Über folgenden Trigger habe ich versucht eine bereits bestehende Zeile aus der Rechnungsdaten-Tabelle zu löschen, falls versucht wird eine neue mit denselben Daten einzufügen:
SQL-Code:
create trigger TRIG_test for rechnungsdaten
before insert
as begin
  if ( (SELECT ausleihid FROM rechnungsdaten
     WHERE old.rechnungsid = new.rechnungsid AND old.ausleihid = new.ausleihid) > 0)
  then
    DELETE FROM rechnungsdaten WHERE ausleihid=new.ausleihid AND rechnungsid=new.rechnungsid;
end;
Obiger Code funktioniert leider gar nicht. Außerdem kenn ich leider nicht alle Funktionen, die Firebird-SQL für Trigger zur Verfügung stellt (vlt. hat da ja jemand eine Online-Referenz zur Hand).

Nun meine Frage gibt es eine elegante Methode um die Eingabe mehrerer identischer Zeilen in der Tabell zu verhindern?
Mit einem Trigger habe ich es versucht, da der UNIQUE-Schlüssel in der Tabellendefinition von "Rechnungsdaten" bisher rausgefallen ist, da mir die IB-Controls eine Exception auswerfen, anstelle es im stillen zu unterbinden.

Außerdem möchte ich möglichst viel Code aus meiner Applikation in die Datenbank auslagern.
MfG EnORItZ
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: SELECT-Statement innerhalb eines Triggers

  Alt 28. Sep 2006, 20:45
Ich würde nicht den vorhandenen Eintarg Löschen, sondern den neuen verhindern.
Du könntest auch einen zusammengesetzen Primärschlüssel verwenden, der beide Felder umfasst.
Markus Kinzler
  Mit Zitat antworten Zitat
EnORItZ

Registriert seit: 8. Sep 2003
11 Beiträge
 
#3

Re: SELECT-Statement innerhalb eines Triggers

  Alt 28. Sep 2006, 20:53
Mir ist gerade aufgefallen was ich eigentlich fürn murks ich da in dem Trigger fabriziert hab...

So gehts...
SQL-Code:
create trigger trig_test for rechnungsdaten
before insert
as begin
   if ( EXISTS(SELECT * FROM rechnungsdaten
         WHERE rechnungsid = new.rechnungsID AND ausleihid = new.ausleihid) )
   then
    DELETE FROM rechnungsdaten
      WHERE ausleihid = new.ausleihid rechnungsid = new.rechnungsid;
end;
@mkinzler:
Wie kann ich denn den neuen Eintrag verhindern?
Und wie läuft das mit dem Schlüssel?
MfG EnORItZ
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: SELECT-Statement innerhalb eines Triggers

  Alt 28. Sep 2006, 20:55
wenn der Primärschlüssel auch mehrern Feldern besteht, so muß die Kombination eindeutig sein und das Einfügen wird automatsch abgelehnt.
Markus Kinzler
  Mit Zitat antworten Zitat
Hansa

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

Re: SELECT-Statement innerhalb eines Triggers

  Alt 29. Sep 2006, 02:28
Was ist das :

Zitat von EnORItZ:
Hallo Leute.

Ich versuche gerade in meiner Rechnungsdaten-Tabelle doppelte eingaben eines Artikels zu vermeiden.

Die Tabelle sieht quasi so aus:
SQL-Code:
create table Rechnungen(
   RechnungsID   Integer,
   KundenID   Integer,
   Datum      Date
);

create table RechnungsDaten(
   RechnungsID   Integer,
   AusleihID   Integer
);
Ist RechnungsID quasi die ID des Datensatzes der Table ? Hängen die Tabellen voneinander ab ? Falls ja : wo ist dann der Verweis von einer Tabelle auf die andere ? Gehe doch systematischer vor : vergeb zunächst mal eine ID, egal für welche Tabelle. Hängt die Tabelle von einer anderenn ab, dann kriegt die eben noch eine die für den Verweis zuständig ist. Glaskugel meint so etwas :

SQL-Code:
create table Rechnungen(
   ID   Integer,
         RECHNNR integer,
   KundenID   Integer,
   Datum      Date
);

create table RechnungsDaten(
   ID   Integer,
         ID_Rechnungen integer, /* erhält Wert von der ID aus table Rechnungen  */
   AusleihID   Integer
);
Den Rest hat mkinzler schon gesagt : im Prinzip wird Schadenswiedergutmachung versucht. So was lässt man aber besser von Anfang an nicht zu. Was soll aber nun gemacht werden, falls das Programm versucht, einen Datensatz einzutragen, der schon da ist ? Ich würde vorab mal sagen, daß ein Trigger der falsche Ansatz ist und das besser in einer SP aufgehoben wäre. Trigger sind gut für automatische Sachen, wie ID-Vergabe, Vorbesetzung oder automatische Änderung von Feldern. Ansonsten kann er das Programm aus den Angeln heben, denn er lauert im Hintergrund und schlägt ohne Warnung zu, sofern eine Bedingung erfüllt ist. Eine SP kann ich gesteuert aus dem eigenen Programm aus aufrufen.
Gruß
Hansa
  Mit Zitat antworten Zitat
hoika

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

Re: SELECT-Statement innerhalb eines Triggers

  Alt 29. Sep 2006, 16:05
Hallo,


der einzige saubere Weg ist ein unique Index.
Das Problem der Trigger ist,
sioe laufen im Kontext der aktuellen Transaktion.

Falls also "zeitgleich" zwei Datensätze eingetragen werden,
sind die wieder doppelt drin.
Das läßt sich zwar etwas über Transaktions-Modi steuern (readcommitted),
aber warum erst rumärgern ?

Was heisst "die IB-Controls zeigen eine Exception an". ??

Starte das Programm doch mal ohne die IDE.


Heiko
Heiko
  Mit Zitat antworten Zitat
Hansa

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

Re: SELECT-Statement innerhalb eines Triggers

  Alt 29. Sep 2006, 19:38
Zitat von hoika:
der einzige saubere Weg ist ein unique Index.
Das Problem der Trigger ist,
sioe laufen im Kontext der aktuellen Transaktion.

Falls also "zeitgleich" zwei Datensätze eingetragen werden,
sind die wieder doppelt drin.
Frage 1 : was nützt ein unique Index ? Meine Frage vorher zielt auf das ab : kann man den überhaupt so zusammenbauen ? Wo ist die Referenz ? Ist der so überhaupt unique zu machen ?

Frage 2 : eine Transaktion läuft immer, sonst geht sowieso nichts. Der Trigger ändert daran nichts. Der Kontext kann commited werden und fertig oder eben Rollback. Einzige Ausnahme : Generatoren. Diese Tatsache fiel hier letztens noch unter den Tisch. 8)

Frage 3 : zeitgleich ? Unter MGA ? Wie soll das gehen ?
Gruß
Hansa
  Mit Zitat antworten Zitat
Antwort Antwort


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 12:11 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