Autor |
Beitrag |
SIJAS
Hält's aus hier
Beiträge: 6
|
Verfasst: Mi 25.07.07 15:57
Hallo Delphiforum, ich bin leider absoluter Neuling im Umgang mit ADO-Komponenten und SQL Befehlen. Nun habe ich ein Problem mit dem folgenden Code: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| AdoQuery6.SQL.Clear; AdoQuery5.SQL.Clear;
AdoQuery5.Close; AdoQuery5.Active:=false; AdoQuery5.SQL.Add('Select ID,Telephone,TelephoneType,AnswerSMS,UserLanguage FROM PersonalData_DB where ID = '+dbgrid3.SelectedField.Text); AdoQuery5.ExecSQL;
AdoQuery5.DisableControls; AdoQuery6.DisableControls; adodataset1.DisableControls; adodataset2.DisableControls;
AdoQuery5.First; while not AdoQuery5.Eof do begin buffer1:= AdoQuery5.Fields[0].AsString; buffer2:= AdoQuery5.Fields[1].AsString; buffer3:= AdoQuery5.Fields[2].AsString; buffer4:= AdoQuery5.Fields[3].AsString; buffer5:= AdoQuery5.Fields[4].AsString;
AdoQuery6.SQL.Clear; AdoQuery6.Active:=false;
QueryString:='INSERT INTO Puffer3([ID]) VALUES("'+buffer1+'")'; AdoQuery6.SQL.Add(QueryString); AdoQuery6.ExecSQL;
AdoQuery6.SQL.Clear; AdoQuery6.Active:=false; AdoQuery6.SQL.Add('INSERT INTO Puffer6 (ID,Telephone,TelephoneType,AnswerSMS,Userlanguage) VALUES ("'+buffer1+'","'+buffer2+'","'+buffer3+'","'+buffer4+'","'+buffer5+'")'); AdoQuery6.ExecSQL;
AdoQuery5.Next; end;
AdoQuery5.Close; AdoQuery6.Close; adodataset1.EnableControls; adodataset2.EnableControls; adoquery5.EnableControls; adoquery6.EnableControls;
AdoQuery9.Active:=false; AdoQuery9.SQL.Clear; AdoQuery9.SQL.Add('SELECT * FROM Puffer6'); AdoQuery9.Active:=true; AdoQuery9.Open; | Mein Problem ist das ich mit ADOQuery5 einen ID-Eintrag suche (später sollen es mehrere werden deshalb die EOF-Schleife) und diesen/diese dann mit ADOQuery6 in eine Access-Datenbank in eine Tabelle "Puffer6" schreibe. Soweit klappt das ganze schon problemlos. Das Problem ist das ich anschließend alle Daten aus "Puffer6" mit AdoQuery9 wieder auslese um die Tabelle in einem DB-Grid anzuzeigen. Hierbei scheint jedoch ADOQuery6 die Schreib-Operation noch nicht abgeschlossen zu haben da es sich immer so verhält das der letzte Eintrag der mit ADOQuery6 geschrieben wurde nicht im ADOQuery9-DBGrid angezeigt wird. Wenn ich mir jedoch die Datenbank direkt mit Access ansehe ist dort der Datenbankeintrag geschrieben worden. Wenn ich den Sleep(1000) Befehl einkommentiere funktioniert es ohne Probleme nur finde ich diese Lösung nicht akzeptabel. Gibt es eine andere Möglichkeit um auf das Ende des vorherigen SQL-Befehls zu warten oder um zu prüfen wann dieser beendet ist? Ich hoffe ich habe alle wichtigen Informationen für mein Problem gepostet und das mir jemand hierbei helfen kann. Auch für andere Tipps zu Optimierung des Codes wäre ich dankbar. Grüße Euer Sijas Moderiert von Klabautermann: Code- durch Delphi-Tags ersetzt
|
|
Agawain
      
Beiträge: 460
win xp
D5, MySQL, devxpress
|
Verfasst: Mi 25.07.07 21:35
hi
nene...also, ob ADO oder nicht ADO...folgendes gilt es zu beherzigen
Vor Veränderungen von Parametern, oder dem Statement die Tabelle schließen...Sieht man auch, wenn man im OI den SQL-Text ändert, die IDE setzt die Tabelle gnadenlos auf Active := false
also
Close
Clear
Add
Klar?
Dann
Active und Open haben ansich die gleich Wirkung
Open verwendet man, wenn, wenn man eine Rückgabemenge erwartet, also bei einem SELECT * FROM... z.B.
ExecSQL verwendet man, wenn man keine Rückgabemenge erwartet, z.B. bei UPDATE, DELETE, INSERT
Überarbeite das Ganze mal nach den von mir genannten Anmerkungen, mach auch ruhig Gebrauch von der F1-Taste, dann sehen wir weiter
Gruß
Aga
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 25.07.07 22:56
Mein Senf:
1. Gib den ADOQueries sinnvolle Namen. dsAdressen (ds=DataSet) ist lesbarer als ADOQuery5.
2. Verwende persistente Felder. Hä? Doppelklick auf die Query, 'Alle Felder hinzufügen' und dann kannst Du auf z.B. den Namen der Adresse direkt mit dsAdressenName.AsString zugreifen. Auch lesbarer.
_________________ Na denn, dann. Bis dann, denn.
|
|
raiguen
      
Beiträge: 374
WIN 2000prof, WIN XP prof
D7EP, MSSQL, ABSDB
|
Verfasst: Do 26.07.07 11:00
Aus meiner Sicht gibt es zwei Optimierungsmöglichkeiten:
Schleife mit parametrisierten Queries
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82:
| if not ADOQuery5.Prepared then begin ADOQuery5.Close; ADOQuery5.SQL.Text := 'SELECT ID,Telephone,TelephoneType,AnswerSMS,UserLanguage ' + 'FROM PersonalData_DB where ID = :ID '; ADOQuery5.Prepared := true; end;
if not ADOQuery6_1.Prepared then begin ADOQuery6_1.Close; ADOQuery6_1.SQL.Text := 'INSERT INTO Puffer3([ID]) VALUES(:buffer1)'; ADOQuery6_1.Prepare; end;
if not ADOQuery6_2.Prepared then begin ADOQuery6_2.Close; ADOQuery6_2.SQL.Text := 'INSERT INTO Puffer6 (ID,Telephone,TelephoneType,AnswerSMS,Userlanguage) ' + 'VALUES (:buffer1, :buffer2, :buffer3, :buffer4, :buffer5'); ADOQuery6_2.Prepare; end;
AdoQuery5.DisableControls; AdoQuery6.DisableControls;
ADOQuery5.Close; ADOQuery5.ParamByName('ID').AsString := dbgrid3.SelectedField.Text; ADOQuery5.Open;
while not AdoQuery5.Eof do begin buffer1:= AdoQuery5.Fields[0].AsString; buffer2:= AdoQuery5.Fields[1].AsString; buffer3:= AdoQuery5.Fields[2].AsString; buffer4:= AdoQuery5.Fields[3].AsString; buffer5:= AdoQuery5.Fields[4].AsString;
ADOQuery6_1.ParamByName('buffer1').AsString := buffer1;
ADOQuery6_2.ParamByName('buffer1').AsString := buffer1; ADOQuery6_2.ParamByName('buffer2').AsString := buffer2; ADOQuery6_2.ParamByName('buffer3').AsString := buffer3; ADOQuery6_2.ParamByName('buffer4').AsString := buffer4; ADOQuery6_2.ParamByName('buffer5').AsString := buffer5;
ADOQuery6_1.ExecSQL; ADOQuery6_2.ExecSQL;
AdoQuery5.Next; end;
AdoQuery5.Close;
adoquery5.EnableControls; adoquery6.EnableControls;
if not ADOQuery9.Prepared then begin AdoQuery9.Close; AdoQuery9.SQL.Text := 'SELECT * FROM Puffer6'; AdoQuery9.Prepare; end;
AdoQuery9.Open; |
Das ständige Neuerstellen eines SQL-Statements kostet Zeit (Speicher belegen, Statement parsen und ausführen, Speicher wieder freigeben);
besser ist es daher, dieses mit Parametern vorzubereiten und anschliessend die entsprechenden Parameter zu setzen.
Was weiterhin Zeit kostet, ist das Einfügen von Datensätzen mittels einer Schleife. Hierzu gibt es (hoffentlich bei ADO auch??) eine
elegantere Möglichkeit
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:
| if not ADOQuery6_1.Prepared then begin ADOQuery6_1.Close; ADOQuery6_1.SQL.Text := 'INSERT INTO Puffer3 ([ID]) ' + 'SELECT ID FROM PersonalData_DB WHERE ID = :ID '; ADOQuery6_1.Prepare; end;
if not ADOQuery6_2.Prepared then begin ADOQuery6_2.Close; ADOQuery6_2.SQL.Text := 'INSERT INTO Puffer6 (ID,Telephone,TelephoneType,AnswerSMS,Userlanguage) ' + 'SELECT ID,Telephone,TelephoneType,AnswerSMS,UserLanguage ' + 'FROM PersonalData_DB where ID = :ID '; ADOQuery6_2.Prepare; end;
ADOQuery6_1.ParamByName('ID').AsString := dbgrid3.SelectedField.Text; ADOQuery6_1.ExecSQL; ADOQuery6_2.ParamByName('ID').AsString := dbgrid3.SelectedField.Text; ADOQuery6_2.ExecSQL; |
Ich habe erstmal bewusst deine wenig aussagekräftigen Query-Benamung genommen, um den Optimierungsweg aufzuzeigen.
Selbstverständlich solltest du wegen der besserne Lesbarkeit/Wartbarkeit den Queries einen klingenden Namen verpassen 
|
|
SIJAS 
Hält's aus hier
Beiträge: 6
|
Verfasst: Do 26.07.07 14:00
Vielen Dank für die schnelle Hilfe.
Ich werd versuchen das so umzusetzen und meine Fortschritte dann hier posten.
Auch das mit den Querybezeichnungen werd ich in Zukunft beherzigen! 
|
|
Klabautermann
      

Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Do 26.07.07 14:45
alzaimar hat folgendes geschrieben: | 2. Verwende persistente Felder. Hä? Doppelklick auf die Query, 'Alle Felder hinzufügen' und dann kannst Du auf z.B. den Namen der Adresse direkt mit dsAdressenName.AsString zugreifen. Auch lesbarer. |
Schöner finde ich FieldByName mindestens genau so lesbar funktioniert aber auch bei Dynamisch erzeugten oder multifunktionalen Table/Querry Objekten.
Also einfach MyTable.FieldByName('MyField').AsString;  .
Für SIJAS vielleicht in dem Zusammenhang auch nützlich: www.delphi-library.d...ry+Arbeiten_363.html
Gruß
Klabautermann
|
|
SIJAS 
Hält's aus hier
Beiträge: 6
|
Verfasst: Do 26.07.07 16:29
Nochmals danke für die vielen Tipps.
Ich bin gerade dabei das ganze nach raiguens Vorschlag zu gestalten, jedoch habe ich jetzt folgendes Problem:
Wenn ich den Parametern für die beiden Querys jetzt Werte zuweisen will, bekomme ich die Fehlermeldung:
"Parameter 'Param1' wurde nicht gefunden".
Habe daraufhin versucht die Parameter über CreateParameter und ADDParameter anzulegen aber meldet immer noch das die Paramter unbekannt sind. Wo mache ich hier noch einen Fehler?
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| if not Query_WritetoPuffer3.Prepared then begin Query_WritetoPuffer3.Close; Query_WritetoPuffer3.SQL.Clear; Query_WritetoPuffer6.Parameters.CreateParameter('Param1',ftUnknown,pdUnknown,255,'');
Query_WritetoPuffer3.SQL.Text := 'INSERT INTO Puffer3 ([ID]) ' + 'SELECT ID FROM PersonalData_DB WHERE ID = :Param1 '; Query_WritetoPuffer3.ParamCheck:=true; Query_WritetoPuffer3.Prepared:=true;
end;
if not Query_WritetoPuffer6.Prepared then begin Query_WritetoPuffer6.Close; Query_WritetoPuffer6.SQL.Clear; Query_WritetoPuffer6.Parameters.CreateParameter('Param2',ftUnknown,pdUnknown,255,''); Query_WritetoPuffer6.SQL.Text := 'INSERT INTO Puffer6 (ID,Telephone,TelephoneType,AnswerSMS,Userlanguage) ' + 'SELECT ID,Telephone,TelephoneType,AnswerSMS,UserLanguage ' + 'FROM PersonalData_DB where ID = :Param2 '; Query_WritetoPuffer6.ParamCheck:=true; Query_WritetoPuffer6.Prepared:=true; end;
Query_WritetoPuffer3.Parameters.GetParamList(Listending,'Param');
Query_WritetoPuffer3.Parameters.ParamByName('Param1').Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer3.ExecSQL; Query_WritetoPuffer6.Parameters.ParamByName('Param2').Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer6.ExecSQL;
Query_Anzeige.Close; Query_Anzeige.SQL.Clear; Query_Anzeige.SQL.Add('SELECT * FROM Puffer6'); Query_Anzeige.Open; |
|
|
raiguen
      
Beiträge: 374
WIN 2000prof, WIN XP prof
D7EP, MSSQL, ABSDB
|
Verfasst: Fr 27.07.07 12:13
Hi  Sofern du den Fehler noch nicht gefunden hast, hier noch einige Hinweise:
SIJAS hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| if not Query_WritetoPuffer3.Prepared then begin Query_WritetoPuffer3.Close; Query_WritetoPuffer3.SQL.Clear; Query_WritetoPuffer6.Parameters.CreateParameter('Param1',ftUnknown,pdUnknown,255,''); ... | |
Das dürfte schon die erste Fehlerquelle sein...
SIJAS hat folgendes geschrieben: | Delphi-Quelltext 1: 2:
| ... Query_WritetoPuffer3.Parameters.GetParamList(Listending,'Param'); | |
Hier müsste es eigentlich auch knallen, da der Parameter mit Namen 'Param' nicht gefunden wird...
Wenn, dann müsste hier Param1 als 'Such'-Kriterium rein...
Warum eigentlich so 'kompliziert' ?? CreateParameter etc kannst du dir schenken, da die Parameterliste automatisch zur Laufzeit erzeugt wird, sobald sich das SQL-Statement ändert bzw neu erstellt wird. Somit kannst du dann bequem mittels ... .Parameters.ParamByName().Value bzw .Parameters[n].Value die entsprechenden Parameterwerte setzen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| if not Query_WritetoPuffer3.Prepared then begin Query_WritetoPuffer3.Close; Query_WritetoPuffer3.SQL.Text := 'INSERT INTO Puffer3 ([ID]) ' + 'SELECT ID FROM PersonalData_DB WHERE ID = :Param1 '; Query_WritetoPuffer3.ParamCheck:=true; Query_WritetoPuffer3.Prepared:=true; end;
if not Query_WritetoPuffer6.Prepared then begin Query_WritetoPuffer6.Close; Query_WritetoPuffer6.SQL.Text := 'INSERT INTO Puffer6 (ID,Telephone,TelephoneType,AnswerSMS,Userlanguage) ' + 'SELECT ID,Telephone,TelephoneType,AnswerSMS,UserLanguage ' + 'FROM PersonalData_DB where ID = :Param2 '; Query_WritetoPuffer6.ParamCheck:=true; Query_WritetoPuffer6.Prepared:=true; end;
Query_WritetoPuffer3.Parameters.ParamByName('Param1').Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer3.Parameters[0].Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer3.ExecSQL;
Query_WritetoPuffer6.Parameters.ParamByName('Param2').Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer6.Parameters[0].Value := dbgrid3.SelectedField.Text; Query_WritetoPuffer6.ExecSQL;
if not Query_Anzeige.Prepared then begin Query_Anzeige.Close; Query_Anzeige.SQL.Clear; Query_Anzeige.SQL.Add('SELECT * FROM Puffer6'); Query_Anzeige.Prepared := true; end; Query_Anzeige.Open; |
|
|
SIJAS 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mo 30.07.07 08:38
Nochmals Danke für deine Hilfe raiguen!
Tut mir leid die beiden Fehler hab ich wohl eingebaut als ich versuchthab das zu lösen
habe jetzt den Quellcode genau so kopiert wie in deinem Post aber es scheitert immer noch an:
Delphi-Quelltext 1:
| Query_WritetoPuffer3.Parameters.ParamByName('Param1').Value := dbgrid3.SelectedField.Text; |
Der Parameter 'Param1' ist unbekannt. Ist die Fehlermeldung.
Auch über den Parameterindex kann ich nicht darauf zugreifen. Ist da noch irgend eine Einstellung an der ADO-Komponente falsch?
|
|
raiguen
      
Beiträge: 374
WIN 2000prof, WIN XP prof
D7EP, MSSQL, ABSDB
|
Verfasst: Di 31.07.07 09:27
hmm...  ... eigentlich dürfte die Fehlermeldung nicht kommen, da an den ADO_kompos nix grossartiges zu Schrauben(=Einstellen) gibt...Habe zum Test auch nur die ADO-Query-Kompo aufs Formular gezogen und keine Einstellungen (ausser dem Connesction-String natürlich)vorgenommen...
|
|
SIJAS 
Hält's aus hier
Beiträge: 6
|
Verfasst: Mi 08.08.07 10:59
tja das mit den Parametern in den ADO-Query funktioniert irgendwie immer noch nicht aber mein Ursprüngliches Problem wurde ja gelöst.
Ich möchte mich nochmals bei allen bedanken die mir weitergeholfen haben! 
|
|
|