Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi INSERT INTO & MS Access (https://www.delphipraxis.net/92102-insert-into-ms-access.html)

Moony 14. Mai 2007 16:27

Datenbank: MS Access • Zugriff über: TADOConnection / TADOCommand

INSERT INTO & MS Access
 
Hallo zusammen,

ich drehe glaube ich hier gleich durch. Habe das folgende Problem:

Ich versuche einen INSERT-Befehl auszuführen, aber dieser sagt mir ständig, dass dort ein Syntaxfehler besteht. Das kann aber irgendwie nicht sein, denn wenn ich diese Abfrage direkt bei MS Access hineinkopiere und ausführe funktioniert das einwandfrei. Die Connection ist richtig gesetzt und die Verbindung steht auch. Ein paar Zeilen zuvor funktionierte ein DELETE-Befehl einwandfrei und dieser nicht. Der Befehl ist ganz simple aufgebaut:

Delphi-Quellcode:
 
SQL := 'INSERT INTO myTable (Field1,Field2,Field3,...Field28) VALUES (Wert1, Wert2, Wert3, ..., Wert28)'
if myDB.Connected then
begin
  myCommand.CommandText := SQL;
  myCommand.Execute;
end;
Bei den Werten kann es natürlich auch vorkommen, dass es Leerstrings sind. In der DB sind alle Felder als Text definiert und können Leerzeichen enthalten.

Ich hoffe ihr könnt mir helfen..... :wall:

Thanks im Voraus. Gruß, Moony

mkinzler 14. Mai 2007 16:34

Re: INSERT INTO & MS Access
 
Stringwerte müssen gequoted sein.

Moony 14. Mai 2007 16:37

Re: INSERT INTO & MS Access
 
Die sind ja mit Hochkommata. Der Befehl würde dann so aussehen:

Delphi-Quellcode:
SQL := 'INSERT INTO myTable (Field1,Field2,Field3,...Field28) VALUES ('''', '''', '''', ..., Wert28)'
if myDB.Connected then
begin
  myCommand.CommandText := SQL;
  myCommand.Execute;
end;
Ich habe gerade festgestellt, dass ich bis 6 Werte einfügen kann, danach jedoch diese Fehlermeldung kommt.

mkinzler 14. Mai 2007 16:38

Re: INSERT INTO & MS Access
 
Was für ein Fehler wird angezeigt?

Moony 14. Mai 2007 16:39

Re: INSERT INTO & MS Access
 
Syntaxfehler in der INSERT INTO-ANweisung

mkinzler 14. Mai 2007 16:40

Re: INSERT INTO & MS Access
 
Zeig mal einen Screenshot. Bzw. wie sieht der erzeugte String aus?

Moony 14. Mai 2007 16:44

Re: INSERT INTO & MS Access
 
Als String steht drin:

INSERT INTO myTable (Feld1,Feld2,Feld3,Feld4,Feld5,Feld6,Feld7) VALUES ('','','','','','','')

Die Fehlermeldung wird genauso angezeigt wie ich es geschrieben habe. Das gibt zumindest die Message von E: Exception -> E.Message aus.

Moony 15. Mai 2007 11:26

Re: INSERT INTO & MS Access
 
Hmmm.....kann mir denn da keiner helfen??? :cry:

marabu 15. Mai 2007 11:52

Re: INSERT INTO & MS Access
 
Hallo,

die Feldnamen hast du wohl kaschiert. Wenn Feld7 gegen die Regeln für Feldnamen verstößt, dann musst du den Feldnamen in eckige Klammern setzen. Wenn alle Felder in ihrer Katalog-Reihenfolge befüllt werden, dann kannst du die Angabe der Feldnamen weglassen. Wenn du einzelne Felder nicht befüllen möchtest, dann kannst du sie einfach auslassen und sie werden auf NULL gesetzt. Verschiebe zum Test mal Feld7 an eine andere Stelle in deinem INSERT-Statement.

Grüße vom marabu

hoika 15. Mai 2007 12:03

Re: INSERT INTO & MS Access
 
Hallo,

benutze Parameter (einfach mal hier suchen),

Oder zeig zumindestens mal die komplette Query.


Heiko

Moony 15. Mai 2007 13:44

Re: INSERT INTO & MS Access
 
@marabu: Es verstößt nicht gegen die Regeln....Die Tabelle wird tausendmal anderweitig verwendet. Ich lese die Feldnamen vorher aus der Accesstabelle aus und übergebe diese dann an den SQL-String folgendermaßen:

Delphi-Quellcode:
Lst := TStringList.Create;
try
  for n := 0 to myaccessDS.FieldCount - 1 do
  begin
    if (Pos('Logo', myaccessDS.Fields.Fields[n].FieldName) = 0) then
      Lst.Add(myaccessDS.Fields.Fields[n].FieldName);
  end;
finally
  myFields := Lst.Commatext;
  Lst.Free;
end;

...

while not MySQLDS.Eof do
begin
  myValues := AnsiQuotedStr(mySQLds.FieldByName('Category').AsString, #39) +',';
  myValues := myValues + AnsiQuotedStr(mySQLds.FieldByName('Name').AsString, #39) +',';
  ...
  SQL := 'INSERT INTO race00 (' + myFields + ') VALUES (' + myValues + ')';
  try
    if myaccessDB.Connected then
    begin
      myaccessComm.CommandText := SQL;
      myaccessComm.Execute;
    end;
  except
  end;
end;
Das mySQLDS besitzt mindestens alle Felder, welche in der Accesstabelle vorhanden sind und mehr.


@hoika: Welche Parameter?

mkinzler 15. Mai 2007 14:03

Re: INSERT INTO & MS Access
 
Zitat:

@hoika: Welche Parameter?
Zitat SQL-Parameter:
SQL-Code:
INSERT INTO myTable (Feld1,Feld2,Feld3,Feld4,Feld5,Feld6,Feld7) VALUES (:wert1, :wert2, ...);
Delphi-Quellcode:
myCommand.Parameters.ParamByName('wert1).Value := ...;

Moony 15. Mai 2007 14:14

Re: INSERT INTO & MS Access
 
Welchen Sinn hat diese Abfrage. davon abgesehen verstehe ich nicht was ich mit der Zuweisung des Doppelpunkts und die von Parambyname machen soll. :?

hoika 15. Mai 2007 14:21

Re: INSERT INTO & MS Access
 
Moonly,

wenn du schon dein SQL-Statement in einer String-Variable
stehen hast, dann sehe die dir doch in dem Debugger mal an.

Ist ziemlich durcheinander dein Code ;)
die Felder sind alle Felder mit LogoX,
die Werte holst du dir aus Category.Wenn jetzt weniger Category als Logo-Felder
existieren, knallt es auf jeden Fall.

Ausserdem rufst du die Insert-Query für jeden Datensatz
in MySQLDS einmal auf, ist das gewollt ?

Vielleicht steht ganz hinten (vor der Schliessenklammer) des Value
laut deinem Code ein Komma zu viel.


Was steht denn nun direkt in der Abfrage (SQL)?


Heiko
PS: mit Parametern ( : ) kannst du das QuotedStr weglassen,
das macht das AsString selber.

mkinzler 15. Mai 2007 14:22

Re: INSERT INTO & MS Access
 
In der Abfrage stellt man nur parameter ein. Diese erkennt man an dem vorangestellten Doppelpunkt. Später füllt man diese mit Werten.
Vorteile:
-Format der Werte wird anhand der Parameter gesetzt -< Keine Quoten nötig
-Abfrage kann öfters verwendet werden und nur die Parameter werden an das DBMS übertragen.

Moony 15. Mai 2007 16:14

Re: INSERT INTO & MS Access
 
@hoika:
1. Wenn du aufgepasst hättest, dann würdest du im source auch sehen, dass ich alle Felder einlese bei denen es NICHT LOGO heißt! Ich hole mir nur einen Wert aus einem anderen Dataset aus einem bestimmten Feld. Diese Felder existieren auch mit 100%iger Sicherheit.

2. Jeder Datensatz soll einzeln eingefügt werden

3. Im Insert-Befehl steht alles vollkommen richtig drin, denn ich habe mir meine SQL-Variable beobachtet, habe den Wert dieser
kopiert und in der Accesstablle direkt als Abfrage eingefügt, und hier funktioniert der Befehle wenn ich diesen ausführe.

@kinzler:
Wenn ich erst die parameter setze und dann erst die Werte dann brauche ich doppelt soviel source. außerdem hat das bis jetzt bei all meinen tausenden von abragen immer so geklappt.

mkinzler 15. Mai 2007 16:29

Re: INSERT INTO & MS Access
 
Du mußt die Abfrage ja nur einmal setzen. In der Schleife brauchst du nur noch die Parameter setzen.

Moony 15. Mai 2007 16:33

Re: INSERT INTO & MS Access
 
das kommt doch aufs gleiche raus ob ich zusätzlich die parameter setze oder ob ich von vornherein die einzelnen werte setze, oder sehe ich das falsch?


nichts desto trotz bleibt dennoch der fehler bestehen...

mkinzler 15. Mai 2007 16:38

Re: INSERT INTO & MS Access
 
Zitat:

das kommt doch aufs gleiche raus ob ich zusätzlich die parameter setze oder ob ich von vornherein die einzelnen werte setze, oder sehe ich das falsch?
-Wieviele Inserts werden eingefügt? Die Abfrage muß nur einmal gesetzt werden (z.B. fix oder im Programmanfang) bei den einzelnen Inserts müssen nur die Parameter gefüllt werden.
-Man muß Typen nicht beachten
-Abfrage ist übersichtlicher.

Moony 15. Mai 2007 17:05

Re: INSERT INTO & MS Access
 
Die Anzahl der Inserts hängt von der Datenmenge ab. Das könnte schon bis zu den 100000en führen.

mkinzler 15. Mai 2007 17:09

Re: INSERT INTO & MS Access
 
Dann würde ich auf jeden Fall Parameter verwenden.

Catbytes 15. Mai 2007 17:18

Re: INSERT INTO & MS Access
 
Was passiert, wenn Du anstatt TADOCommand, TQuery verwendest?

Also so:

Delphi-Quellcode:
ADOquery1.SQL.Clear;
ADOquery1.SQL.Add(SQL);
ADOquery1.ExecSQL;

Moony 16. Mai 2007 08:05

Re: INSERT INTO & MS Access
 
Kann ich denn mit einem normalen Query änderungsbefehle ausführen?

Davon abgesehen funktioniert jetzt immer noch nichts. Weder die normale Übergabe des SQL-Strings, noch die Parametergeschichte, noch das Auswechseln des ADOCommands durch das ADOQuery.

Das ist doch zum heulen!!!! :cry:

hoika 16. Mai 2007 08:38

Re: INSERT INTO & MS Access
 
Hallo,

du hattest geschrieben, du kannst bis 6 Werte eintragen
Rufe mal fest als Test die folgende auf (Feld 6 und 7 verdreht)

INSERT INTO myTable (Feld1,Feld2,Feld3,Feld4,Feld5,Feld7,Feld6) VALUES ('','','','','','','')


Ausserdem hast du noch immer nicht gesagt, wie die Felder heissen,
haben die irgendwelche Sonderzeichen/Leerzeichen.

Sogar beim Umsteig auf den ms-sql Server musste ich mal Feldnamen ändern,
weil er die nicht erlaubte, Access aber schon.

Als letztes baue eine Test-DB (mdb) und ein Programm,
was genau den Fehler beim Insert erzeugt.
und lade beides hier hoch.

Ansonsten ist das hier nur noch Rätselraten.


Heiko

Moony 16. Mai 2007 08:56

Re: INSERT INTO & MS Access
 
Also, als erstes sind alle Feldnamen ohne Sonderzeichen oder Leerzeichen.
So sieht der SQL String übersetzt aus:

SQL-Code:
INSERT INTO race00 (Category,Name,PassNumber,ValidDays,ValidZones,GrandStand,Section) VALUES ('MEINE KATEGORIE','MEIN NAME (P)','00-2007-03-0103','1111','11111111','','')
Die fEldnamen stimmen überein, da diese Datenbank überall anderweitig bereits seid Jahren in dem Aufbau verwendet wird. Wie bereits gesagt funktioniert der SQL-Befehl direkt bei einer Abfrage in dieser Accesstabelle ja einwandfrei. Nur über den Source mit dem ADOCommand nicht.
Das Tauschen der Felder funktioniert ebenso wenig. Egal welches Feld ich an diese Stelle gebe. Das Tauschen ist im Normalfall auch egal, da alle Felder in der Tabelle den Datentyp "Text" definiert haben. der einzige unterschied zwischen den Feldern ist die zulässige Größe, aber die habe ich bereits für jedes Feld überprüft. Bei allen Feldern wird ebenfalls ein Leerstring zugelassen.

Moony 16. Mai 2007 09:55

Re: INSERT INTO & MS Access
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, habe jetzt ein Testprogramm mit der DB gemacht, wobei ich den größten Teil der Felder rausgenommen habe. Des Weiteren werden hier die Werte aus dem Memo entnommen, in meinem eigentlichen Programm ist es ein Query, welches an einen MySQL-Server angebunden ist. Die Anzahl der Feldnamen kann geändert werden, sowie die Feldwerte. Um mehrere Datensätze hinzuzufügen in dem Memo eine Zeile pro Datensatz verwenden.

Ich hoffe das hilft weiter.

Catbytes 16. Mai 2007 10:07

Re: INSERT INTO & MS Access
 
"Diese Datenbank weist ein unbekanntes Format auf". :(

Ich habe leider "nur" Office 2000. Kannst Du die DB mal als 2000er zur Verfügung stellen?

Moony 16. Mai 2007 10:12

Re: INSERT INTO & MS Access
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier nochmal die DB in Access 2000

hoika 16. Mai 2007 10:59

Re: INSERT INTO & MS Access
 
Hallo,

jo, in Access geht es.
Ich kann mir jetzt noch vorstellen, dass deine Connection
nicht auf der richtigen MDB oder das Ado-Dingens
auf dem falschen Connection liegt.


Heiko

marabu 16. Mai 2007 11:14

Re: INSERT INTO & MS Access
 
Hallo,

der Feldname [Section] muss in eckige Klammern gesetzt werden! Name und Row gefallen mir zwar auch nicht so recht, aber ADO hat keine Schwierigkeiten mit denen.

Grüße vom marabu

Moony 16. Mai 2007 11:30

Re: INSERT INTO & MS Access
 
Das funktioniert, aber warum? Section ist doch kein reserviertes Wort, oder doch?

hoika 16. Mai 2007 11:53

Re: INSERT INTO & MS Access
 
Hallo,

Section ist ein Teil eines Forms (ähnlich wie Panels in Delphi).
Warum das in einer SQL-Abfrage als reserviertes Wort ist,
musst du MS fragen.

siehe auch

http://www.btgi.net/reservedwords.cfm


Heiko

Moony 16. Mai 2007 12:25

Re: INSERT INTO & MS Access
 
hmmm, komisch. Ich hatte damit noch nie Probleme und diese DB wird schon ewig benutzt. Ebenfalls auf einem SQL- und MySQL-Server. Aber wenn mans weiß kann man sich ja darauf einstellen.


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