AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi InterBase - DBX-Fehler Hersteller-Fehler
Thema durchsuchen
Ansicht
Themen-Optionen

InterBase - DBX-Fehler Hersteller-Fehler

Ein Thema von delphinub23 · begonnen am 20. Mai 2013 · letzter Beitrag vom 22. Mai 2013
Antwort Antwort
delphinub23

Registriert seit: 27. Okt 2010
Ort: Chemnitz
110 Beiträge
 
Delphi XE3 Professional
 
#1

InterBase - DBX-Fehler Hersteller-Fehler

  Alt 20. Mai 2013, 19:29
Datenbank: InterBase • Version: XE3 • Zugriff über: TSQLConnection
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;
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: InterBase - DBX-Fehler Hersteller-Fehler

  Alt 20. Mai 2013, 21:14
Eine Transaction, die nur SELECT-Anweisungen zum Inhalt hat (also ausschlieslich lesender Zugriff) ist sinnlos.
Du kannst also die Transaction in 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;
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.995 Beiträge
 
Delphi 12 Athens
 
#3

AW: InterBase - DBX-Fehler Hersteller-Fehler

  Alt 20. Mai 2013, 21:43
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
delphinub23

Registriert seit: 27. Okt 2010
Ort: Chemnitz
110 Beiträge
 
Delphi XE3 Professional
 
#4

AW: InterBase - DBX-Fehler Hersteller-Fehler

  Alt 21. Mai 2013, 12:43
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.
  Mit Zitat antworten Zitat
delphinub23

Registriert seit: 27. Okt 2010
Ort: Chemnitz
110 Beiträge
 
Delphi XE3 Professional
 
#5

AW: InterBase - DBX-Fehler Hersteller-Fehler

  Alt 22. Mai 2013, 10:47
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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:20 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