Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi InterBase - DBX-Fehler Hersteller-Fehler (https://www.delphipraxis.net/174943-interbase-dbx-fehler-hersteller-fehler.html)

delphinub23 20. Mai 2013 19:29

Datenbank: InterBase • Version: XE3 • Zugriff über: TSQLConnection

InterBase - DBX-Fehler Hersteller-Fehler
 
Hallo Delphianer,

ich habe Informationen in einer Log-Datei stehen, die in eine Datenbank geschrieben werden müssen.
Den Inhalt einer Textdatei lade ich in eine TStringList, welche ich dann iterativ durchgehe und die Informationen von einer Zeile in die Datenbank schreibe.
Ich führe in dieser Prozedur mehrere Anfragen an die Datenbank aus, weshalb ich vor jede Query ein BeginTransaction rufe.
Leider bekomme ich nach rund 4000 Datensätzen einen DBX-Fehler Hersteller-Fehler zugeworfen und kann damit nichts anfangen.

Wofür steht der Fehler? Oder, sind meine Routinen der eigentliche Auslöser für den Absturz der DB?

Das sind die Funktionen, die ich rufe, um SQL Queries an die DB zu schicken
Delphi-Quellcode:
function TStatisticsDataModule.SQLSelect(var ResultSet: TDataSet;
  const Fields, From: string; const Where: string = ''; const GroupBy: string = '';
  const OrderBy: string = ''): Integer;
var
  sqlQuery: string;
  selectClause: string;
  fromClause: string;
  whereClause: string;
  groupByClause: string;
  orderByClause: string;
  Transaction: TDBXTransaction;
begin
  selectClause := Format('SELECT %s', [Fields]);
  fromClause := Format('FROM %s', [From]);
  whereClause := Format('WHERE %s', [Where]);
  groupByClause := Format('GROUP BY %s', [GroupBy]);
  orderByClause := Format('ORDER BY %s', [OrderBy]);
  sqlQuery := Format('%s %s', [selectClause, fromClause]);
  if Length(Where) > 0 then
    sqlQuery := Format('%s %s', [sqlQuery, whereClause]);
  if Length(GroupBy) > 0 then
    sqlQuery := Format('%s %s', [sqlQuery, groupByClause]);
  if Length(OrderBy) > 0 then
    sqlQuery := Format('%s %s', [sqlQuery, groupByClause]);

  Transaction := FSQLConnection.BeginTransaction;
  try
    Result := FSQLConnection.Execute(sqlQuery, nil, ResultSet);
  finally
    FSQLConnection.CommitFreeAndNil(Transaction);
  end;
end;

function TStatisticsDataModule.SQLUpdate(const Table: string;
  const FieldsAndValues: string;
  const Where: string = ''): Integer;
var
  sqlQuery: string;
  updateClause: string;
  setClause: string;
  whereClause: string;
  Transaction: TDBXTransaction;
begin
  updateClause := Format('UPDATE %s', [Table]);
  setClause := Format('SET %s', [FieldsAndValues]);
  whereClause := Format('WHERE %s', [Where]);
  sqlQuery := Format('%s %s', [updateClause, setClause]);
  if Length(Where) > 0 then
    sqlQuery := Format('%s %s', [sqlQuery, whereClause]);

  Transaction := FSQLConnection.BeginTransaction;
  try
    Result := FSQLConnection.ExecuteDirect(sqlQuery);
  finally
    FSQLConnection.CommitFreeAndNil(Transaction);
  end;
end;

function TStatisticsDataModule.SQLInsert(const Table: string;
  const Values: string;
  const Where: string = ''): Integer;
var
  sqlQuery: string;
  insertClause: string;
  valuesClause: string;
  whereClause: string;
  Transaction: TDBXTransaction;

  sl: TStrings;
begin
  insertClause := Format('INSERT INTO %s', [Table]);
  valuesClause := Format('VALUES (%s)', [Values]);
  whereClause := Format('WHERE %s', [Where]);
  sqlQuery := Format('%s %s', [insertClause, valuesClause]);
  if Length(Where) > 0 then
    sqlQuery := Format('%s %s', [sqlQuery, whereClause]);

  Transaction := FSQLConnection.BeginTransaction;
  try
    Result := FSQLConnection.ExecuteDirect(sqlQuery);
  finally
    FSQLConnection.CommitFreeAndNil(Transaction);
  end;
und das der ein PSEUDO-Aufruf:
Delphi-Quellcode:
  for Entry in LogFile.Content do
  begin
    SQLSelect({DS},{WERT1},...);
    SQLUpdate({WERT1},...);
    SQLInsert({WERT1},...);
  end;

sx2008 20. Mai 2013 21:14

AW: InterBase - DBX-Fehler Hersteller-Fehler
 
Eine Transaction, die nur SELECT-Anweisungen zum Inhalt hat (also ausschlieslich lesender Zugriff) ist sinnlos.
Du kannst also die Transaction in
Delphi-Quellcode:
function TStatisticsDataModule.SQLSelect
ruhig entfernen.

Eigentlich sollte der Auflauf so aussehen, dass es nur eine Transaction gibt:
Delphi-Quellcode:
BeginTransaction;
try
  for Entry in LogFile.Content do
  begin
    SQLSelect({DS},{WERT1},...);
    if not DS.IsNull then
      SQLUpdate({WERT1},...)
    else
      SQLInsert({WERT1},...);
  end;
  CommitTransaction;
except
  AbortTransaction;
  raise;
end;

Uwe Raabe 20. Mai 2013 21:43

AW: InterBase - DBX-Fehler Hersteller-Fehler
 
Zitat:

Zitat von sx2008 (Beitrag 1215846)
Eine Transaction, die nur SELECT-Anweisungen zum Inhalt hat (also ausschlieslich lesender Zugriff) ist sinnlos.

Das gilt für eine einzelne SELECT-Anweisung - bei mehreren kann es ohne Transaktion durchaus zu inkonsistenten Daten zwischen den SELECT-Anweisungen kommen. Ohne Transaktion können auch zwei identische SELECT-Anweisungen unterschiedliche Ergebnisse liefern.

delphinub23 21. Mai 2013 12:43

AW: InterBase - DBX-Fehler Hersteller-Fehler
 
Danke für die Antworten. Ich habe jetzt probiert nur eine Transaction über der Interation auszuführen - gleiche Fehlermeldung nach ca. 6000 Datensätzen (DBX-Fehler Hersteller-Fehler 101).

Ich werde das Gefühl nicht los, dass es an meinen Generators innerhalb der Datenbank liegt. Jeder Generator ist zuständig für einen Table, der, wenn ein neuer Datensatz hinzugefügt wird, eine neue eindeutige ID für dieses Datensatz bereitstellt.

Ich habe Generatoren gewählt um das AUTO_INCREMENT Feature von MySQL nachzubauen.

Hier ein Beispiel eines Generators:
Code:
CREATE GENERATOR "GEN_LDATASET";

CREATE TRIGGER "DATASET_ID_AUTO_INCREMENT" FOR "LDATASET"
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.Dataset_ID is NULL) THEN
    NEW.Dataset_ID = GEN_ID(gen_ldataset, 1);
END
 ;
Vielleicht fällt Euch ja hier ein Fehler auf.

delphinub23 22. Mai 2013 10:47

AW: InterBase - DBX-Fehler Hersteller-Fehler
 
Leider habe ich nicht herausgefunden warum der DBX-Fehler mit einer TSQLConnection aufgetreten ist. Nun habe ich es mit einer IBDatabase, IBQuery und IBTransaction gelöst.

Hier treten keine Fehler auf. Es ist nur etwas langsam, was aber an den fehlenden Indizes meiner Tabellen liegen wird.

Vielen Dank :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:54 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