![]() |
Datenbank: MSSQL • Version: 2017 • Zugriff über: FireDAC
TFDEventAlerter HowTo
Hallo...:P
Mein letzter Strohhalm...euch zu fragen. :zwinker: SOLL: Die Datenbank "soll" ein Event (pro Tabelle) auslösen. Der Client soll dann seine Datenmenge aktualisieren können. IST: Ich habe alles ausprobiert...es wird kein Event ausgelöst. :cry: Infos: ![]() ![]() Beispiel ausprobiert: ![]() Ich habe mich für die Variante "_FD_EVENTS UPDATE notification" entschieden. 1. Broker ist on 2. _FD_EVENTS Tablelle wurde erstellt 3. 'evtUsers' Event wurde als Datensatz in der Tabelle angelegt (über Register der Komponente) (Die Komponente versucht jedesmal den Datensatz anzulegen -> stille Exception bei Vorhandensein...macht Spaß im Debug. :evil:) Zitat:
5. TFDPhysMSSQLDriverLink wird der gebraucht? :gruebel: 6. Beim Beenden oder Close kommt eine stille Exception bei der Freigabe des Threads der Komponente. :kotz: Zitat:
Delphi-Quellcode:
procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin FWaitThread.Terminate; // <- hier FWaitCommand.AbortJob(True); end; Ergebnis: kein Event wird ausgelöst. :evil: Was habe ich vergessen? Was ist falsch? :? Wie kommt denn der Broker von MSSQL ins Spiel? Der Alerter braucht doch nur im Task den Wert des Values vergleichen und das Event auslösen..oder? :gruebel: Testcode:
Delphi-Quellcode:
procedure TForm1.ale1Alert(ASender: TFDCustomEventAlerter; const AEventName: string; const AArgument: Variant);
begin qry1.Refresh; end; procedure TForm1.btn1Click(Sender: TObject); begin con1.Connected := True; qry1.SQL.Text := 'select * from Users'; qry1.Open; end; procedure TForm1.btn2Click(Sender: TObject); begin con1.Close; end; procedure TForm1.btn3Click(Sender: TObject); begin ale1.Signal('evtUsers', 1); end;
Delphi-Quellcode:
object Form1: TForm1
Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 511 ClientWidth = 933 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False DesignSize = ( 933 511) PixelsPerInch = 96 TextHeight = 13 object grd1: TDBGrid Left = 32 Top = 88 Width = 889 Height = 401 Anchors = [akLeft, akTop, akRight, akBottom] DataSource = ds1 TabOrder = 0 TitleFont.Charset = DEFAULT_CHARSET TitleFont.Color = clWindowText TitleFont.Height = -11 TitleFont.Name = 'Tahoma' TitleFont.Style = [] end object btn1: TButton Left = 32 Top = 40 Width = 75 Height = 25 Caption = 'Open' TabOrder = 1 OnClick = btn1Click end object btn2: TButton Left = 113 Top = 40 Width = 75 Height = 25 Caption = 'Close' TabOrder = 2 OnClick = btn2Click end object btn3: TButton Left = 264 Top = 40 Width = 75 Height = 25 Caption = 'btn3' TabOrder = 3 OnClick = btn3Click end object con1: TFDConnection Params.Strings = ( 'DriverID=MSSQL' 'MARS=No' 'Server=XXX' 'User_Name=Blubb' 'Password=Test' 'Database=Bla') Connected = True LoginPrompt = False Left = 824 Top = 24 end object qry1: TFDQuery Connection = con1 Left = 32 Top = 200 end object ds1: TDataSource DataSet = qry1 Left = 80 Top = 200 end object ale1: TFDEventAlerter Connection = con1 Names.Strings = ( 'evtUsers') SubscriptionName = 'Events' Options.AutoRegister = True Options.MergeData = dmNone Options.AutoRefresh = afNone OnAlert = ale1Alert Left = 824 Top = 80 end object lnk1: TFDPhysMSSQLDriverLink Left = 760 Top = 24 end end |
AW: TFDEventAlerter HowTo
Funktioniert denn das FireDAC.TFDEventAlerter Beispiel?
Falls du die Samples nicht installiert hast: ![]() |
AW: TFDEventAlerter HowTo
Hi,
ich hatte es vor ein paar Wochen ebenfalls versucht unter MSSQL (2008) den TFDEventAlerter mit den Demos zum laufen zu bekommen und habe alle angegebenen Verfahren getestet. Leider vergebens- das Thema wurde daher erst einmal zurück gestellt. Es wurde nun mit Poll-Verfahren umgesetzt... :( Unter Firebird hat es nach 5 Min. funktioniert :). Nur die Portfreigabe/Firewall dabei beachten, da auf einem anderen Port <> 3050 kommuniziert wird. |
AW: TFDEventAlerter HowTo
Könnte auch mit der verwendeten Delphi-Version zusammenhängen. Bei Sydney gab es da wohl ein paar Verbesserungen. Wenn ich Zeit finde, kann ich das Beispiel ja mal mit 10.4.2 und MSSQL ausprobieren.
|
AW: TFDEventAlerter HowTo
Moin...:P
Zitat:
Der Alerter legt mit jedem Register den Service und einen Queue (wahrscheinlich wegen der Einstellungen) mit jeweils einer GUID im Namen an. Diese werden beim Beenden wieder entfernt. Soweit so gut. Wenn das Programm aber "abgeschossen" oder über die IDE beendet wird, bleiben die Einträge in den Systemtabellen vorhanden. :roll: Ist wahrscheinlich technisch nicht anders machbar...:? PS: Ich hatte auch einmal nur den Namen ohne GUID gesehen...aber nur einmal. :gruebel: Danke :wink: PS: Zitat:
evt. Vorteil: kein Broker benötigt. |
AW: TFDEventAlerter HowTo
Hast du es mal "manuell" versucht?
(CREATE EVENT NOTIFICATION) Im Postgres hatten wir auch immer wieder mit dem TPgAlerter Problemchen, also dass der oftmals einfach garnicht empfing, oder nach einem Reconnect die Arbeit ebenfalls einstellte (obwohl er darauf eigentlich reagieren sollte, so weit ich es im Code sah). Am Ende hab ich nun im AfterConnect der Connection die Registrierung selbst gemacht (EXECUTE mit einem Registrieungs-Statement) und dann es kommt nun im OnNotify der TPgConnecton an ... und das nun auch sehr zuverlässig. (bisher keine Probleme mehr bemerkt) |
AW: TFDEventAlerter HowTo
Zitat:
Ich sollte dies ebenfalls haben, bringe es aber einfach nicht zum laufen. Das FDEventAlerter1Alert wird nicht getriggert. Hoffe, du findest die Ursache... |
AW: TFDEventAlerter HowTo
Hat zu diesem Thema jemand eine Lösung?
Mir wäre das viel lieber, als alle paar Sekunden auf neue oder geänderte Daten zu prüfen. Bin für jeden Tipp oder kleines Beispiel dankbar... |
AW: TFDEventAlerter HowTo
Hallöle...8-)
Zitat:
1. EventTypes
Delphi-Quellcode:
2. In der Datenbank eine Tabelle:
TRefreshDataType = (rdtComplete)
...
Code:
3. Ein Thread der das ganze überwacht (Auszug)
create table _Events
( ID int IDENTITY(1,1) NOT NULL, EventType int NOT NULL, EventName nvarchar(30) NOT NULL, EventCurrentGUID uniqueidentifier NOT NULL, CONSTRAINT Events_pk PRIMARY KEY CLUSTERED (ID ASC) ) create index ixEventType on _Events (EventType) GO /* Events */ insert into _Events (EventType, EventName, EventCurrentGUID) values (0, 'Complete', NEWID()) GO /* Trigger*/ create trigger TR_Complete on Complete for insert, update, delete as begin update _Events set EventCurrentGUID = NEWID() where EventType = 0 end GO
Delphi-Quellcode:
Wenn ein Event eintritt, verteile ich das über eine Message an die Forms und die gibt das an die entsprechende Formlogik weiter. Die Formlogik kennt die Events auf die sie reagieren soll und aktualisiert ggf. die Datenmenge der Form.
procedure TDatabaseEventThread.Execute;
var Qry: TFDQuery; procedure LoadEvents; begin Qry.Open; while not Qry.Eof do begin FGUIDDict.Add(Qry.FieldByName('EventType').AsInteger, TGuidField(Qry.FieldByName('EventCurrentGUID')).AsGUID); Qry.Next; end; end; procedure CheckEvents; var PairCurrent: TPair<Integer, TGUID>; begin FGUIDDictCurrent.Clear; Qry.Close; Qry.Open; while not Qry.Eof do begin FGUIDDictCurrent.Add(Qry.FieldByName('EventType').AsInteger, TGuidField(Qry.FieldByName('EventCurrentGUID')).AsGUID); Qry.Next; end; for PairCurrent in FGUIDDictCurrent do begin if FGUIDDict.ContainsKey(PairCurrent.Key) then // sicher ist sicher begin if not (FGUIDDict.Items[PairCurrent.Key] = PairCurrent.Value) then begin FGUIDDict.Items[PairCurrent.Key] := PairCurrent.Value; // zurückschreiben FLastEvent := TRefreshDataType(PairCurrent.Key); // DataType für Synchronisierung SyncOnDataChange; end; end; end; end; begin inherited; Qry := FDatabase.CreateQuery; try Qry.SQL.Text := FDatabase.GetSQLByName('DB_EVENTS'); LoadEvents; while not Self.Terminated do begin if FDatabase.IsEventDataChangeActive then begin CheckEvents; end; Sleep(1000); end; finally Qry.Free; end; end; ...fertsch. :wink: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:11 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 by Thomas Breitkreuz