![]() |
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:
und das der ein PSEUDO-Aufruf:
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;
Delphi-Quellcode:
for Entry in LogFile.Content do
begin SQLSelect({DS},{WERT1},...); SQLUpdate({WERT1},...); SQLInsert({WERT1},...); end; |
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:
ruhig entfernen.
function TStatisticsDataModule.SQLSelect
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; |
AW: InterBase - DBX-Fehler Hersteller-Fehler
Zitat:
|
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:
Vielleicht fällt Euch ja hier ein Fehler auf.
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 ; |
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 11:13 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