Delphi-PRAXiS
Seite 2 von 4     12 34      

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

himitsu 3. Mär 2012 10:46

AW: Insert Optimierung
 
Beim Bulk-Insert mußt du aber aufpassen.

Klient und Datenbankserver müssen auf die selben Speicherplätze zugreifen und sollten womöglich auch noch über die selben Netzwerkadressen verfügen (abgesehn man nutzt im Klient einen Dateipfad, und gibt dann dem Server einen anderen Pfad mit, unter welchem er die Datei findet)

Bei Postgres-COPY könnte man zwar auch über STDIN die Daten übergeben, aber ich hatte nicht rausbekommen, ob und wie man das via einem ExecSql-Befehl durch ein Delphi-Programm mit übertragen kann.

Bernhard Geyer 3. Mär 2012 10:49

AW: Insert Optimierung
 
Zitat:

Zitat von Furtbichler (Beitrag 1154249)
Zitat:

Zitat von Franzelchen (Beitrag 1154213)
Wo ist der Fehler?

i wird nicht initialisiert

Von Vorteil ist wer lesen kann. Nicht umsonst gibt der Compiler Warnmeldungen aus. :stupid:

Franzelchen 3. Mär 2012 13:14

AW: Insert Optimierung
 
Delphi-Quellcode:
var i:Integer;
var startzeit,stopzeit : TDateTime;

begin
startzeit := now;
i := 0; //   Initialisierung von i
Screen.Cursor := crHourGlass;
ZConnection.Database := 'c:\msql\firedb.fdb';
 Zquery1.SQL.Text:='INSERT INTO TestTabelle (Wert1, Wert2) VALUES(:v1, :v2), (:v3, :v4), (:v5, :v6), (:v7, :v8), (:v9, :v10)';
 while i <= SG1.RowCount-1 do
  begin
       with ZQuery1.params do
       begin
        ParamValues['v1']:=SG1.Cells[0, i];
        ParamValues['v2']:=SG1.Cells[1, i];
        ParamValues['v3'] := SG1.Cells[0, i + 1];
        ParamValues['v4'] := SG1.Cells[1, i + 1];
        ParamValues['v5'] := SG1.Cells[0, i + 2];
        ParamValues['v6'] := SG1.Cells[1, i + 2];
        ParamValues['v7'] := SG1.Cells[0, i + 3];
        ParamValues['v8'] := SG1.Cells[1, i + 3];
        ParamValues['v9'] := SG1.Cells[0, i + 4];
        ParamValues['v10']:= SG1.Cells[1, i + 4];

      end; // with
  ZQuery1.ExecSQL;
   i := i+5;
  end; // i
Screen.Cursor := crDefault;
stopzeit := now;
Panel1.Caption :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
Das Problem dabei: Wo vorher keine Fehlermeldung war, erscheint jetzt

Code:
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project2.exe ist eine Exception der Klasse EZSQLException aufgetreten. Meldung: 'SQL Error: Dynamic SQL Error SQL error code = -104 Token unknown - line 1, column 51 ,. Error Code: -104. Invalid token The SQL: INSERT INTO Testtabelle (Wert1, Wert2) VALUES(?, ?), (?, ?), (?, ?), (?, ?), (?, ?); '. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
Spalte 51?? Es gibt nur 2 Spalten.

Bitte um Übersetzung dieser Fehlermeldung.


@ Furtbichler @ Himitsu

bulk insert Erkläre mir einer diesen Begriff. Ich meine gelesen zu haben, daß bulk insert bei Firebird nicht möglich ist.
Der Link von Furtbichler verweist auf externalTables. Um dies nutzen zu können, muß ich doch mir unbekannte Veränderungen an der firebird.conf Datei vornehmen!??

Zitat:

Zitat von himitsu (Beitrag 1154264)
Beim Bulk-Insert mußt du aber aufpassen.

Klient und Datenbankserver müssen auf die selben Speicherplätze zugreifen und sollten womöglich auch noch über die selben Netzwerkadressen verfügen (abgesehn man nutzt im Klient einen Dateipfad, und gibt dann dem Server einen anderen Pfad mit, unter welchem er die Datei findet)

Klient und Server sind auf ein und demselben Rechner. Reicht das?

himitsu 3. Mär 2012 13:22

AW: Insert Optimierung
 
Joar, wenn dann noch die Zugriffsrechte auf das Verzeichnis passend sind.
Bei uns auf'm Server hab ich ein privates virtuelles SUBST-Laufwerk, wo meine Verzeichnisse reingemappt sind ... der SQL-Server hat auf diese nicht direkt Zugriff drauf, auf dieses Arbeits-Laufwerk, außer über den originalen Pfad.


Nicht Spalte 51, sondern Zeichen 51.
Das ist auf den SQL-Text bezogen > Zeile und Spalte/Zeichen/Buchstabe.
Die schließende Klammer ) nach dem ersten Wertepaar? :gruebel:

[edit]
Oder das Komma danach? :gruebel:
http://www.firebirdsql.org/refdocs/l...21-insert.html
Eventuell kann Firebird das nicht? :shock:

Vielleicht dann einfach so. (Das andere wäre halt kürzer)
SQL-Code:
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
Es geht ja einfach nur darum, den Traffik und die Anzahl der Anfragen an den Server zu verringern.

Franzelchen 3. Mär 2012 14:02

AW: Insert Optimierung
 
So etwa??

Delphi-Quellcode:
procedure TForm1.InputDataset3Click(Sender: TObject);
var  i:Integer;
var  startzeit,stopzeit : TDateTime;

begin
i := 0;
startzeit := now;
Screen.Cursor := crHourGlass;
ZConnection.Database := 'c:\msql\firedb.fdb';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v1, :v2)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v3, :v4)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v5, :v6)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v7, :v8)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v9, :v10)';

 while i <= SG1.RowCount-1  do
  begin
       with ZQuery1.params do
       begin
        ParamValues['v1']:=SG1.Cells[0, i];
        ParamValues['v2']:=SG1.Cells[1, i];
        ParamValues['v3'] := SG1.Cells[0, i + 1];
        ParamValues['v4'] := SG1.Cells[1, i + 1];
        ParamValues['v5'] := SG1.Cells[0, i + 2];
        ParamValues['v6'] := SG1.Cells[1, i + 2];
        ParamValues['v7'] := SG1.Cells[0, i + 3];
        ParamValues['v8'] := SG1.Cells[1, i + 3];
        ParamValues['v9'] := SG1.Cells[0, i + 4];
        ParamValues['v10']:= SG1.Cells[1, i + 4];

      end; // with
  ZQuery1.ExecSQL;
   i := i+5;
  end; //  i
Screen.Cursor := crDefault;
stopzeit := now;
Panel1.Caption :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
Kompilierung einwandfrei

Bei Ausführung: Kann Parameter v1 nicht finden

oder müssen die jeweiligen Parameter hinter dem jeweiligen insert Befehl stehen,
aber nein, denn dann stehen die insert Befehle ja innerhalb der while Schleife, in welcher sie ja nichts zu suchen haben (siehe Beitrag 8)

himitsu 3. Mär 2012 14:08

AW: Insert Optimierung
 
Du überschreibst ja auch immer wieder die Werte komplett, es gilt also immer nur die letzte Zuweiseung. :zwinker:

Fällt aber bestimmt auf, wen man mal nachsieht/debuggt, was für eine Query letzendlich ausgeführt wird. :angle2:
Delphi-Quellcode:
ZQuery1.SQL.Text :=
    'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';

ZQuery1.SQL.Clear;
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';

with ZQuery1.SQL do begin
  Clear;
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';
end;
(die letzen beiden Queries lassen sich auch sehrt schön automatisch generieren)

mkinzler 3. Mär 2012 14:10

AW: Insert Optimierung
 
Wobei eine parametrisierte Anweisung schneller sein sollte als eine Skript mit der wiederholten Anweisung.

Bulk-Insert könnte man auch mit Hilfe einer externen Tabelle (Textdatei) versuchen.

himitsu 3. Mär 2012 14:48

AW: Insert Optimierung
 
Man kann es kaum glauben, aber Programmieren hat tatsächlich etwas mit Mathematik zu tun.
Und wie schonmal erwähnt, fehlt noch der Rest.

Delphi-Quellcode:
procedure TForm1.InputDataset3Click(Sender: TObject);
const
  Anzahl = 30;
var
  StartZeit, StopZeit: TDateTime;
  i, i2: Integer;
begin
  StartZeit := Now;
  Screen.Cursor := crHourGlass;
  ZConnection.Database := 'c:\msql\firedb.fdb';

  ZQuery1.SQL.Clear;
  for i2 := 0 to Anzahl - 1 do
    ZQuery1.SQL.Add(Format('INSERT INTO dat12006 (Begriff, Frage) VALUES (:v%d, :v%d);', [i2 * 2, i2 * 2 + 1]));

  for i := 0 to SG1.RowCount div Anzahl - 1 do begin
    for i2 := 0 to Anzahl - 1 do begin
      ZQuery1.Params[i2 * 2 + 0].Value := SG1.Cells[0, i * Anzahl + i2];
      ZQuery1.Params[i2 * 2 + 1].Value := SG1.Cells[1, i * Anzahl + i2];
    end;
    ZQuery1.ExecSQL;
  end;

  //ZQuery1.SQL.Text := 'INSERT INTO dat12006 (Begriff, Frage) VALUES (:v0, :v1);';
  //for i := SG1.RowCount div Anzahl * Anzahl to SG1.RowCount - 1 do begin
  //  ZQuery1.Params[0].Value := SG1.Cells[0, i];
  //  ZQuery1.Params[1].Value := SG1.Cells[1, i];
  //  ZQuery1.ExecSQL;
  //end;

  if SG1.RowCount mod Anzahl > 0 then begin
    ZQuery1.SQL.Clear;
    for i2 := 0 to SG1.RowCount mod Anzahl - 1 do
      ZQuery1.SQL.Add(Format('INSERT INTO dat12006 (Begriff, Frage) VALUES (:v%d, :v%d);', [i2 * 2, i2 * 2 + 1]));

    i := SG1.RowCount div Anzahl;
    for i2 := 0 to SG1.RowCount mod Anzahl - 1 do begin
      ZQuery1.Params[i2 * 2 + 0].Value := SG1.Cells[0, i * Anzahl + i2];
      ZQuery1.Params[i2 * 2 + 1].Value := SG1.Cells[1, i * Anzahl + i2];
    end;
    ZQuery1.ExecSQL;
  end;

  Screen.Cursor := crDefault;
  StopZeit := Now;
  Panel1.Caption :='SuchZeit : ' + FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
PS: Mit einer ordentlichen Einrückung braucht man kaum noch kommentare, um die Zusammenhänge zu erkennen. (wie z.B. wozu das END gehört)

Franzelchen 3. Mär 2012 16:51

AW: Insert Optimierung
 
@ himitsu

Ich bedanke mich erst einmal für deine Hilfe, leider liefert die Einspielung deines Quelltextes folgende Fehlermeldung:
Code:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project2.exe ist eine Exception der Klasse EZSQLException aufgetreten. Meldung: 'SQL Error: Dynamic SQL Error SQL error code = -104 Token unknown - line 1, column 54 INSERT. Error Code: -104. Invalid token The SQL: INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?); INSERT INTO dat12006 (Begriff, Frage) VALUES (?, ?);; '. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
Spalte 54 weist auf
Code:
VALUES (:v%d, :v%d);'
hin. Ich habe viel zuwenig Ahnung von SQL um mit Sicherheit sagen zu können, daß es an dem fehlenden Parameter v liegt ??
Code:
ZQuery1.Params[i2 * 2 + 0].Value := SG1.Cells[0, i * Anzahl + i2];

himitsu 3. Mär 2012 16:58

AW: Insert Optimierung
 
An V vollte es nicht liegen.
Man kann entweder über den Namen den Wert eines Parameters setzen,
oder über den Index. (der erste Parameter im Statemant hat den Index 0)

Das ist also alles das Selbe, nur das nach einem Index nicht erst gesucht werden muß:
Delphi-Quellcode:
SQLQuery1.Params[0].Value
SQLQuery1.Params.Items[0].Value
SQLQuery1.Params.ParamByName('Name des ersten Parameters').Value
SQLQuery1.Params.ParamValues['Name des ersten Parameters']
ExecSQL sollte doch mehrere SQL-Statements verarbeiten können? :gruebel:


Mal aus Interesse:
Was passiert denn bei
Delphi-Quellcode:
Anzahl = 1;
?


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr.
Seite 2 von 4     12 34      

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