Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Insert into (https://www.delphipraxis.net/204167-insert-into.html)

Walter Landwehr 1. Mai 2020 07:08

Datenbank: Firebird • Version: 2.5 • Zugriff über: IBO

Insert into
 
Hallo ich habe folgenden Code:
Delphi-Quellcode:
                  while not (PatblattQry.EoF = True) do
                  begin
                      if (PatblattQry.FieldByName('TYP').AsString <> 'Z') then
                      begin
                          InsRechnungsPositionenQry.ParamByName('RECHNUNGNR').AsInteger := RechnungNr;
                          InsRechnungsPositionenQry.ParamByName('PATIENTENNUMMER').AsInteger := PatientQry.FieldByName('PATIENTENNUMMER').AsInteger;
                          InsRechnungsPositionenQry.ParamByName('BEHANDLUNGSDATUM').AsString := PatblattQry.FieldByName('BEHANDLUNGSDATUM').AsString;
                          if (MitarbeiterQry.Locate('ANREDE_NAME',PatblattQry.FieldByName('BEHANDLER').AsString,[]) = True) then begin
                             InsRechnungsPositionenQry.ParamByName('MITARBEITERNUMMER').AsString := MitarbeiterQry.FieldByName('MITARBEITERNUMMER').AsString;
                             InsRechnungsPositionenQry.ParamByName('BEHANDLER').AsString := MitarbeiterQry.FieldByName('ANREDE_NAME').AsString;
                          end;
                          InsRechnungsPositionenQry.ParamByName('GEBUEHNR').Value := PatblattQry.FieldByName('GEBUEHNR').Value;
                          InsRechnungsPositionenQry.ParamByName('CODENR').Value := PatblattQry.FieldByName('CODENR').Value;
                          InsRechnungsPositionenQry.ParamByName('SUCHWORT').Value := PatblattQry.FieldByName('SUCHWORT').Value;
                          InsRechnungsPositionenQry.ParamByName('TEXT').Value := PatblattQry.FieldByName('TEXT').Value;
                          InsRechnungsPositionenQry.ParamByName('GOAENR').Value := PatblattQry.FieldByName('GOAENR').Value;
                          InsRechnungsPositionenQry.ParamByName('MENGE').Value := PatblattQry.FieldByName('MENGE').Value;
                          InsRechnungsPositionenQry.ParamByName('TYP').Value := PatblattQry.FieldByName('TYP').Value;
                          InsRechnungsPositionenQry.ParamByName('FAKTOR').Value := PatblattQry.FieldByName('FAKTOR').Value;
                          InsRechnungsPositionenQry.ParamByName('EINZELPREIS').Value := PatblattQry.FieldByName('EINZELPREIS').Value;
                          if PatblattQry.FieldByName('STEUERCODE').Value = Null then
                            InsRechnungspositionenQry.ParamByName('STEUERCODE').Value := 0
                          else
                            InsRechnungsPositionenQry.ParamByName('STEUERCODE').Value := PatblattQry.FieldByName('STEUERCODE').Value;
                          InsRechnungsPositionenQry.ParamByName('STEUERBETRAG').Value := PatblattQry.FieldByName('STEUERBETRAG').Value;
                          InsRechnungsPositionenQry.ParamByName('STEUERSATZ').Value := PatblattQry.FieldByName('STEUERSATZ').Value;
                          InsRechnungsPositionenQry.ParamByName('GESAMTBETRAG').Value := PatblattQry.FieldByName('GESAMTBETRAG').Value;
                          InsRechnungsPositionenQry.ParamByName('KATEGORIE').Value := PatblattQry.FieldByName('KATEGORIE').Value;
                          InsRechnungsPositionenQry.ParamByName('SPLITTING').Value := PatblattQry.FieldByName('SPLITTING').Value;
                          InsRechnungsPositionenQry.ParamByName('MEDIKAMENT').Value := PatblattQry.FieldByName('MEDIKAMENT').Value;
                          InsRechnungsPositionenQry.ParamByName('GEBUEHRENNR').Value := PatblattQry.FieldByName('GEBUEHRENNR').Value;
                          InsRechnungsPositionenQry.ParamByName('TARIF').Value := PatblattQry.FieldByName('TARIF').Value;
                          if (PatblattQry.FieldByName('TYP').AsString = 'M') then
                             InsRechnungsPositionenQry.ParamByName('Medikament').AsString := 'J'
                          else
                             InsRechnungsPositionenQry.ParamByName('Medikament').AsString := 'N';
                          InsRechnungsPositionenQry.ParamByName('Anlage').asDatetime := Date;
                          InsRechnungsPositionenQry.ParamByName('AnlageBenutzer').asString := Constants.User.UserName;
 ----> dauert 43 Sekunden InsRechnungsPositionenQry.ExecSQL;
                      end;
                      PatblattQry.Next;
                  end;
                  {$ENDREGION}
Dazu folgende SQL Anweisung
Delphi-Quellcode:
Insert into tbl_Rechnungspositionen(
RECHNUNGNR, PATIENTENNUMMER, BEHANDLUNGSDATUM, MITARBEITERNUMMER, BEHANDLER, GEBUEHNR, CODENR,
SUCHWORT, TEXT, GOAENR, MENGE, FAKTOR, EINZELPREIS, STEUERCODE, STEUERBETRAG, STEUERSATZ, GESAMTBETRAG,
KATEGORIE, SPLITTING, MEDIKAMENT, GEBUEHRENNR, TYP, Anlage, AnlageBenutzer, GEHOERTZU, TARIF)
Values(
:RECHNUNGNR, :PATIENTENNUMMER,:BEHANDLUNGSDATUM, :MITARBEITERNUMMER, :BEHANDLER, :GEBUEHNR, :CODENR,
:SUCHWORT, :TEXT, :GOAENR, :MENGE, :FAKTOR, :EINZELPREIS, :STEUERCODE, :STEUERBETRAG, :STEUERSATZ, :GESAMTBETRAG,
:KATEGORIE, :SPLITTING, :MEDIKAMENT, :GEBUEHRENNR, :TYP, :Anlage, :AnlageBenutzer, :GEHOERTZU, :TARIF)
Die Anweisung InsRechnungsPositionenQry.ExecSQL; dauert 43 Sekunden. Viel zu lange.:oops:

In der Tabelle sind etwas über 520000 Datensätze.

Hat jemand eine Idee warum das so lange dauert.

hoika 1. Mai 2020 07:15

AW: Insert into
 
Hallo,
43 sek pro Aufruf oder für die 500.000 Datensätze?

Hängen an den Queries noch was dran (Grid)?
Ist die InsertQuery prepared?
Sind auf der Positionstabelle viele Indizes/Trigger?

schotti65 1. Mai 2020 07:23

AW: Insert into
 
Da können doch zig Anhängigkeiten, Indizes, Trigger, sonstwas auf der Tabelle definiert sein. Ich würd als Erstes mit der kompletten SQL Anweisung die Gegenprobe in einem interaktiven Tool machen. Dann weisst du, ob's an Delphi oder an der DB liegt.

Walter Landwehr 1. Mai 2020 08:06

AW: Insert into
 
An hoika:

Pro Datensatz nicht die 500000
Kein Grid keine weiteren Komponenten.
2 Indizes ; 10 Trigger
prepared := False

An schotti65 :

In IBExpert sehr schnell ca. 1 Sekunde

Neumann 1. Mai 2020 08:24

AW: Insert into
 
Wie sehen denn die Trigger aus, gibt es BeforePost / AfterPost Events?

Normal sollte dieser Vorgang < 50 ms dauern.

Walter Landwehr 1. Mai 2020 08:43

AW: Insert into
 
Liste der Anhänge anzeigen (Anzahl: 1)
Kein Before- oder AfterPost

Im Anhang die Trigger.

jobo 1. Mai 2020 09:02

AW: Insert into
 
Wenn es in einem externen Tool schnell geht- wie erwartet-, scheint es ein Codeproblem zu sein.
Was macht die Schleife, die Du mit gepostet hast?
Ist sichergestellt, dass keine Mehrfachinserts mit (verschluckten) Fehlern auftreten?

jobo 1. Mai 2020 09:12

AW: Insert into
 
Nach Übersicht in den Triggern ist es ja doch wohl etwas komplexer.
Es werden diverse Tabellen aktualisiert, dabei werden "sogar" gruppierende Abfragen gemacht, was jetzt nicht mehr unbedingt ne Frage von Millisekunden ist.
Alle Operationen in den Triggern sind der Existenz passender Indizes unterworfen, wenn es um Mengen jenseits von 100000 geht.

Wenn am Ende noch Rechnungsdaten (Gesamtbeträge) aktualisiert werden, kann ich mir auch gut vorstellen, dass es hier einen Sperrkonflikt gibt (der bei einem "Testins Blaue" durch eine autarke DB Query nicht auftritt).

Walter Landwehr 1. Mai 2020 09:48

AW: Insert into
 
Nur mal so zur Info.

Seit Jahren läuft dies eigentlich ohne Probleme. Am Code ist schon seit Jahren nichts geändert worden. Aber seit 2 - 3 Monaten trat dann plötzlich diese Verzögerung ein. Kann es an Firebird liegen?

p80286 1. Mai 2020 09:58

AW: Insert into
 
Zitat:

Zitat von jobo (Beitrag 1463304)
Ist sichergestellt, dass keine Mehrfachinserts mit (verschluckten) Fehlern auftreten?

Zum einen dies, zum anderen, woher kommt der PK? (kann ich natürlich überlesen haben)

Ich hab so etwas immer so gemacht: (pseudocode)
SQL-Code:
 Insert into table (pk,RechnNr) (newpk,:rechnNr);
Update table set........
where pk=(selekt pk from table where rechnnr=:rechnr)
Etwas umständlich aber wenn Rechnungsnummer eindeutig ist gibt es keine Müllupdates.
ggf sollte natürlich vorher überprüft werden ob die Rechnungsnummer besreits existiert.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:22 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf