Autor Beitrag
Zero5
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Mi 23.02.05 23:17 
Hi,

ich füge über Delphi Datensätze aus Dateien in eine DB ein. Mein Problem: Beim 968. Datzensatz läuft er in eine Exception: 'Ein Parameterobjekt ist nicht ordnungsgemäß definiert. Inkonsistente oder unvollständige Informationen wurden angegeben.'
Der Clou: Wenn ich den SQL-Befehl auswerte, in den Query-Analyzer von SQL-Server kopier und dann ausführ, funktionierts.
Danach starte ich mein Delphi-Programm wieder, es wird abgefragt, ob der Datensatz schon existiert, nachdem ich Ihn manuell über den Queryanalyzer eingefügt habe, tut er das, deshalb wird nicht erneut versucht, ihn einzufügen, er springt also über die Datei drüber und liest jetzt die Dateien weiter und fügt die nachfolgenden DS ein. Irgendwann läuft er dann wieder in eine Exception.

Syntax:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  ADOQuery1.Prepared := true;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add(sql);
  ADOQuery1.ExecSQL;


Kann mir irgendwer erklären, was diese Meldung zu bedeuten hat ?

Gruß
Christian
embae
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Do 24.02.05 15:37 
Hi,
das scheint ein bug zu sein.
Schau mal unter dem folgenden Link nach, da findest du näheres dazu.

groups.google.de/gro...rland.com%26rnum%3D3

Vielleicht hilft dir das weiter.
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Do 24.02.05 20:14 
Hi,

danke Dir, in dem Betrag ist von Delphi 4 und 5 die Rede, ich benutze Delphi 7 Enterprise.
(Habe ich vergessen zu erwähnen). Somit sollte dieser Bug eigentlich mittlerweile behoben sein.
Weiterhin habe ich keine ADODB.pas sondern nur die *.dcu, so dass ich auch den beschriebenen Workaround nicht machen kann.
Hab bei mir nur die ADODB2000.pas gefunden, irgendeine Ahnung ob ich die benutzen kann ?
Wenn nicht, was kann ich sonst tun ?

Gruß
Christian
csa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP
Delphi 2005 Prof.
BeitragVerfasst: Do 24.02.05 23:23 
Hallo,

der D7-Quellcode sieht genau so aus wie in dem Bugfix angegeben, da sollte die Ursache des Fehlers also nicht liegen.

Ich habe einen ähnlichen Fehler mit einem SQL Server - leider auf Kundenrechnern, sodass ich der Ursache nicht auf den Grund gehen kann. Und nur dort, nirgendwo sonst reproduzierbar. Aber das Auskommentieren von "ADOQuery1.Prepared := true;" hat als Workaround erst mal geholfen.

Gruß
Christoph
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Fr 25.02.05 19:19 
Titel: Leider keine Änderung des Problems
Hi,

vielen Dank für Deinen Tip, aber auch das auskommentieren des

ausblenden Delphi-Quelltext
1:
ADOQuery1.Prepared := true					


sowie das explizite Setzen auf
ausblenden Delphi-Quelltext
1:
ADOQuery1.Prepared := true					


brachten leider keine Änderung.
Trotzdem vielen Dank !

Gruß
Christian
csa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP
Delphi 2005 Prof.
BeitragVerfasst: Fr 25.02.05 23:32 
Titel: Parameter.Datatype
hmm.. - dann würde ich mal die Parameter untersuchen, vielleicht konnte für einen der Parameter kein Datentyp ermittelt werden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    for i := 0 to ADOQuery1.Parameters.Count - 1 do
    begin
      Assert(
        not (ADOQuery1.Parameters[i].Datatype = ftUnknown)
      , ADOQuery1.Parameters[i].Name);
    end;


Gruß
Christoph
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Sa 26.02.05 14:33 
Titel: Da scheint etwas im Argen zu sein...!
Hi,

erstmal vielen Dank, hab´s mit dem Code von Dir untersucht, es wird ein Exception ausgelöst !

Verstehe nur einiges nicht:

1. Der Assert-Befehl löst dann eine Exception aus wenn ein boolscher Ausdruck false ist.
Um im Falle eines
ausblenden Delphi-Quelltext
1:
   Datatype[i] = ftUnknown					

(true) ein false zu bekommen setze ich ein not
davor.
Das ist aber nicht das Gleiche wie
ausblenden Delphi-Quelltext
1:
2:
 
   Datatype[i] <> ftUnknown

, oder ?

2. Was hat es mit diesen Parametern von ADOQuery auf sich ? Ich werde aus der Delphi-Hilfe einfach nicht
schlau. Bei allen Abfragen die durchlaufen, ist der Parameter-Count gleich 0
Nur bei der, die nicht läuft, ist er 1.
Beim
ausblenden Delphi-Quelltext
1:
2:
 
   Name[i]

wird als Inhalt

ausblenden Delphi-Quelltext
1:
2:
 
   '\TestofTest\''Anastacia''How'

angezeigt, der vollständige SQL-String sieht so aus:
ausblenden Delphi-Quelltext
1:
  'INSERT INTO id3_test (filename, filepath, id3v2_artist, id3v2_title, id3v2_album, id3v2_year, id3v2_genre)  VALUES ('Anastacia - Freak of Nature 06 - How come the World don`t stop.mp3', 'E:\TestofTest\', 'Anastacia', 'How come the world don`t stop', 'Freak of Nature', '2001', 'Pop')'					


Wie bekomm ich jetzt das Problem gelöst ?
Hab´s schon damit probiert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
If ADOQuery1.Parameters[i].Datatype = ftUnknown then
begin
   ADOQuery1.Parameters[i].Datatype := ftString;
end;


löst aber leider eine Exception aus, ist wahrscheinlich auch logisch, aber mir sind eben die Hintergründe nicht ganz klar.

Gruß
Christian
csa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

Win XP
Delphi 2005 Prof.
BeitragVerfasst: Sa 26.02.05 15:40 
Titel: QuotedStr?
achso - in dem SQL-Statement sind gar keine Platzhalter für Parameter (Platzhalter für Parameter beginnen mit einem Doppelpunkt) - dann sollte ADOQuery1.Parameters.Count immer gleich 0 sein.

Die Assertion war dazu da, herauszufinden, ob irgendein Parameter den Datatype = ftUnknown hat - in dem Fall wurde die Exception EAssertionFailed ausgelöst. Normalerweise verwendet man Assertions, um sicher zu gehen, dass nach einer Änderung des Quelltextes nicht etwas an einer ganz anderen Stelle mikadomäßig heruntergefallen ist. Bspw. Prüfung der übergebenen Parameterwerte einer Prozedur: Assert(Assigned(UebergebenesObjekt)). Wenn man ausliefert, schaltet man die Assertions wg. Performance aus.

Ein Assert(ADOQuery1.Parameters.Count = 0) sollte also keine Exception auslösen.

Meine Vermutung bzgl. Ursache:

Wenn das Statement mit "'INSERT INTO ..''' + X + '''..'" zusammengestellt wird, darf X kein einzelnes Hochkommata enthalten. Besser ist es, stattdessen mit QuotedStr (Unit SysUtils) zu arbeiten: "'INSERT INTO ..' + QuotedStr(X) + '..'" - wenn innerhalb des Strings Hochkommata enthalten sind, werden diese verdoppelt.

Gruß
Christoph
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Sa 26.02.05 20:38 
Titel: Hab die Ursache jetzt gefunden !
Hi,

:D

danke für den Hinweis, das mit den QuotedStr hatte ich schon eingebaut, mir ist nur nicht ganz klar warum Du immer 3 Anführungszeichen verwendest, bei mir funktionierts nur mit einem, weil dann feuer ich ja auf den SQL-Server eine solche Abfrage: 'INSERT...', also zu Beginn und Ende mit Anführungszeichen und das geht bei mir nicht gut.

Aber schwamm drüber, bei mir läuft´s auf einen Fehler, wenn in einem String zwei Apostroph, also das hier => ´
enthalten sind, bei einem funktioniert´s, bei zwei eben nicht.
Woran liegt das, weil wenn ich die Abfrage wie gesagt in den QueryAnalyzer einfüg, nimmt er die eiwandfrei, es muss also an Delphi liegen, in dem Fall setzt er mir dann einen Parameter mit Datatyp ftUnknown.

Gruß
Christian
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: So 27.02.05 15:43 
Titel: Funktioniert jetzt => Danke !
Hi,

habe es jetzt anders gelöst:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
//Einen leeren Datensatz abfragen
ADOQuery1.SQL.Text := 'SELECT * FROM ' + XMLDocument1.DocumentElement.
                         ChildNodes['Reference'].ChildNodes['Tables']
                         .ChildNodes['Id3Table'].Text + ' WHERE 0 = 1';
  ADOQuery1.Open;

  //Einfügemodus starten
  ADOQuery1.Append;

  //Alle Spalten setzen in der Art: ADOQuery1['spaltenname'] := 'testString';
  with XMLDocument1.DocumentElement.ChildNodes['Reference'].
       ChildNodes['Columns'].ChildNodes['Input'do
  begin     
     for i:=0 to ChildNodes.Count - 1 do
     begin
        if ChildNodes[i].Text <> '' then
        begin           
           ADOQuery1[childNodes[i].LocalName] := mp3Arr[i];
        end;
     end;
  end;

   //Datensatz abschicken
  ADOQuery1.Post;


Vielen Dank !

Gruß
Christian :D