SQL Ereignisse
Zuletzt geändert: 11.06.2023 13:20

SQL-Ereignisse (EULANDA SQL-API) #

Problemstellung #

Über Trigger lassen sich eine Vielzahl von SQL-Ereignissen abfangen und gesondert behandeln. Es ist möglich besondere Prüfungen beim Speichern einer Adresse durchzuführen oder Änderungen an Daten zu protokollieren. Trigger arbeiten stets auf Tabellenebene. Dadurch ist das mögliche Einsatzgebiet auf diejenigen Ereignisse beschränkt, die primär eine Tabelle betreffen resp. das Anlegen, Ändern und Löschen eines oder mehrerer Datensätze. Komplexe Vorgänge - wie beispielsweise das Umwandeln eines Auftrags in einen Lieferschein - lassen sich nur schwer greifen. Um bei dem Beispiel zu bleiben: Beim Umwandeln eines Auftrags in einen Lieferschein werden etliche Einzelaktionen innerhalb einer Transaktion durchgeführt.

  • Anlegen des Lieferscheinkopfes
  • Anlegen der Positionen oder Teilpositionen
  • ggf. Prüfung des Kreditlimits
  • Setzen des Auftragsstatus
  • Füllen der Umsetzungsmatrix zwischen Auftragspositionen und Lieferscheinpositionen
  • ggf. Anlegen von Titeln, die im Auftrag verwendet werden
  • etc..

Diese Auflistung ist beispielhaft und nicht vollständig. Die durchzuführenden Aktionen variieren von einer EULANDA®-Version zur nächsten. Sicherlich könnte man einen Trigger schreiben, der beim Ändern des Auftragsstatus eine benutzerdefinierte Aktionen durchführt. Aber man kann nicht sicherstellen, dass zu diesem Zeitpunkt bereits alle anderen Aktionen durchgeführt worden sind. Man kann beispielsweise nicht sicher sein, dass alle Lieferscheinpositionen angelegt sind. Um dieser Limitierung des Trigger-Konzeptes zu begegnen führt EULANDA® eine neue Klasse von Ereignissen auf Server-Ebene ein. Im Nachfolgenden finden Sie eine Liste der verfügbaren Ereignisse.

Serverseitige Ereignisse #

Eventid Eventname Bemerkung
10000 AfBuchen.OnSuccess Auftrag Buchen
10003 AfEdit.OnSuccess Auftrag weitererfassen
10004 AfStornoBuchung.OnSuccess Auftrag Buchung stornieren
10005 TraAfLf_DoJob.OnSuccess Umwandlung eines Auftrags in einen Lieferschein HINWEIS: Je nach Einstellungen kann dieses Ereignis ausgelöst werden, nachdem der Lieferschein gebucht wurde. Falls buchungsrelevante Änderungen vorgenommen werden müssen, so ist das Ereignis 10019 zu verwenden.
10006 TraLfRe_DoJob.OnSuccess Umwandlung eines Lieferscheins in eine Rechnung
10007 AnpCreate.OnSuccess Anlegen einer Angebotsposition
10008 AfpCreate.OnSuccess Anlegen einer Auftragsposition
10009 LfBuchen.OnSuccess Lager des Lieferscheins wird gebucht
10010 TraAnAf.OnSuccess Nach dem Umwandeln eines Angebots in einen Auftrag
10011 KfBuchen.OnSuccess Wenn die Erfassung der Bestellung abgeschlossen wird (STRG+B)
10012 KfpCreate.OnSuccess Anlegen einer Bestellposition
10013 AfStornoRest.OnSuccess Stornieren der Restmengen des Auftrags
10014 AfCreate.OnSuccess Anlegen eines Auftrags unabhängig davon ob er kopiert oder komplett neu angelegt wird
10015 AnCreate.OnSuccess Anlegen eines Angebots unabhängig davon ob es kopiert oder komplett neu angelegt wird
10016 CbBuchen.OnSuccess nach dem Buchen des Lagers eines Kassenbons
10017 CbStornoBuchen.OnSuccess Stornierung der Lagerbuchung zum Kassenbeleg. Dies geschieht hauptsächlich beim Löschen eines alten Kassenbelegs.
10018 CbBuchen.Before wird vor dem Lagerbuchen des Kassenbelegs aufgerufen. Die Tabelle „cnLbJob“ mit den Buchungsinformationen ist dabei bereits gefüllt. (RefTyp = „CB“, RefId = @ObjId )
10019 LfBuchen.Before wird vor dem Lagerbuchen des Lieferscheins aufgerufen.
10020 LfLdInit.OnSuccess intern: Vorbereitung der Lagerbuchung von Lieferscheinen
10021 JbLdInit.OnSuccess intern: Vorbereitung der Lagerbuchung von Stücklisten
10022 LLInitAbLd.OnSuccess intern: Vorbereitung der Lagerbuchung von Lagerbelegen (erste Buchung)
10023 LLInitZuLd.OnSuccess intern: Vorbereitung der Lagerbuchung von Lagerbelegen (zweite Buchung)
10024 ReStorno.OnSuccess nach dem Löschen von Rechnungen
10025 KfDelete.OnSuccess Nach dem Löschen von Bestellungen
10026 K.BeforefDelete wird vor dem Löschen von Bestellungen aufgerufen
10027 AfBuchen.Before wird vor dem Buchen des Auftrags aufgerufen
10028 TraKfWe.OnSuccess Nach dem Anlegen einer Lieferung zu einer Bestellung
10029 SpnInit.onSuccess Nach Initialisierung einer SEPA-Nachricht
10030 SpnRender.onSuccess Nach der XML-Erzeugung der SEPA-Nachricht
10031 TraAfLf_DoJob.BeforeBuchen in Vorbereitung
10032 ReStorno.Before in Vorbereitung - wird aufgerufen, bevor die Rechnung storniert wird, um dies ggf. zu unterbinden
10033 LLBuchen.OnSuccess in Vorbereitung - nach dem erfolgreichen Buchen eines Lagerbelegs (Wareneingang, Inventur, Lieferung etc.)
10034 LLZuBuchen.OnSuccess in Vorbereitung - nach dem erfolgreichen Buchen der Alternativbuchung eines Lagerbelegs (Wareneingang, Inventur, Lieferung etc.). Wird von Standardmodulen nicht verwendet
10035 LLStornoBuchen.Before in Vorbereitung - wird vor dem Stornieren eines Lagerbelegs aufgerufen. Die ursprüngliche Buchungs ist zu diesem Zeitpunkt noch vorhanden
10036 AfShopCreate.OnSuccess wird nach dem Anlegen eines Auftrags ausgelöst, der über die Shop-Schnittstelle eingegangen ist.
10037-10041 Versandübergabe reserviert
10042 LfVersanduebergabe.OnHandover ab 7.0.19 wird nach der Versandübergabe ausgelöst
10043 LfVersanduebergabe.OnPrint ab 7.0.19 wird nach dem Drucken der Versandetiketten ausgelöst
10044-10049 Versandübergabe reserviert

Unterstützte Ereignisse in Ihrer Version #

Die grundlegenden Ereignisse wurden erst in EULANDA 2007 eingeführt. Um eine Liste der von Ihrer Datenbank unterstützten Ereignisse zu erhalten führen Sie folgenden Befehl aus:

IF OBJECT_ID('cnEventType') IS NULL
  RAISERROR('In dieser Eulanda-Version werden noch keine SQL-Ereignisse unterstützt',16,1)
ELSE SELECT id,Name FROM cnEventType ORDER BY id

Asynchrone/verzögerte Ausführung #

Ab Version 7.0.19 ist auch eine asynchrone Aufrufen der Ereignisprozedur möglich. Der ursprüngliche Vorgang, der das Ereignis auslöst wird hierbei zunächst abgearbeitet. Die Prozedur wird dann nach einer vorgegebenen Zeitspanne aufgerufen. Hierzu muss in der Tabelle cnEventSubscriber in der Spalte AsyncDeferredSeconds ein Wert größer oder gleich 0 eingetragen werden. Dieser gibt die Wartezeit in Sekunden an, die mindestens gewartet wird, bis die Prozedur ausgeführt wird.

Die verzögerte Ausführung setzt voraus, dass die Prozedur cn_Queue_HandleCnEvents regelmäßig - z.B. alle 5 Minuten - aufgerufen wird. Dies kann bei der Standard Edition des SQL-Server über den SQL-Server Agent erfolgen. Bei Einsatz der Express Edition kann dies über die Windows Aufgabenplanung erreicht werden.

Die die Prozedur nicht mehr in derselben Transaktion des ursprünglichen Vorgangs ausgeführt wird kann dieser selbstredend nicht mehr abgebrochen werden. Eine Rückgabe eines Wertes ungleich Null wird entsprechend ignoriert bzw. kann in zukünftigen Versionen auch als Fehler gewertet werden. Die Asynchrone Ausführung ist beispielsweise für zeitaufwändige Prozesse gedacht, die die ursprüngliche Abarbeitung (Buchen des Lieferscheins etc.) nicht unnötig verzögern sollen. Des Weiteren ist es empfehlenswert zu prüfen, ob das übergebene Objekt noch existiert und dem gewünschten Status entspricht. Denn es kann durchaus vorkommen, dass zum Beispiel ein Lieferschein zwischenzeitlich bereits in eine Rechnung umgewandelt oder wieder storniert wurde.

Prozedur Prototyp #

Die Behandlung eines solchen Ereignisses wird als Prozedur implementiert. Dabei muss die Prozedur streng nach folgendem Schema aufgebaut sein:

CREATE PROC cn_user_evtXXX
  @SubsId int,
  @ObjType char(4),
  @ObjId int
AS

SET NOCOUNT ON

  RAISERROR('Fehlermeldung',16,1)
  RETURN -1

  RETURN 0

Beispiel #

Über nachfolgenden SQL-Code wird eine Preisprüfung implementiert, die bei Unterschreitung des Einkaufspreises das Buchen des Auftrags verhindert

CREATE PROC cn_user_evtAfBuchen_EkPruefung
  @SubsId int,
  @ObjType char(4),
  @ObjId int
AS

SET NOCOUNT ON

DECLARE @Pos int
SELECT TOP 1 @Pos = afp.PosNummer 
FROM dbo.AuftragPos afp
WHERE afp.KopfId = @ObjId AND afp.Basis > afp.VkRab

IF @@ROWCOUNT > 0
BEGIN
RAISERROR('Der Einkaufspreis wurde in Position %d unterschritten',16,1,@Pos)
RETURN -1
END ELSE RETURN 0

GO

INSERT cnEventSubscriber (EventId, Vendor, ProcName)
VALUES(10000, 'USER', 'cn_user_evtAfBuchen_EkPruefung')