Beliebige Zeichenkette in MySql schreiben
-
Hi,
mein Problem ist folgendes. Ich habe eine beliebige Zeichenkette, von der ich die Anfangsadresse und die Länge weiss. Diese Kette muss ich in einem MySql-Blob-Objekt speichern. Das Schwierige ist, die Eingaben an MySql mache ich über die C-Api per Strings, z.B.
AnsiString DBStrg; DBStrg = "insert into BspTab set C1 = 1, C2 = 'blah'"; mysql_query (hDB, DBStrg.c_str());
Da in dieser beliebigen Zeichenkette auch \0 vorkommen kann, bin ich jetzt mit Strings ziemlich in der Klemme, da die ja danach immer den Rest abschneiden. Hat jemand eine Idee, wie ich das lösen kann?
Eine Überlegung von mir ist, \0 mit einer "Zeichenersetzung" zu umgehen. Aber vielleicht kann ich mir das ja ersparen.Thx, Maffe
-
wird dir wohl nichts anderes übrig bleiben, wenn es keine mysql_query Version gibt, wo du die Länge des Strings angeben kannst, also die Funktion nicht mit dem \0-C-Strings arbeitet (btw. dann kannst du aber wahrscheinlich auch keine string Klasse dafür benutzen)
-
mysql_real_query
Hier muss man die Länge angeben. mysql_query ist NULL_Terminiert. Dh. das der SQL-Query abgeschnitten wird wenn eine Terminierung gefunden wird. mysql_real_query() macht dies nicht.
Vorher noch mysql_escaped_string() aufrufen.
Die ist bei BLOB immer brauchbar. Insbesonders wenn es sich z.B. um Bild-Dateien handelt unentbehrlich.
-
Hmm,
hört sich ganz gut an. Das mit mysql_real_query() hört sich schon mal sehr gut an.
Allerdings ist mir jetzt immer noch nicht klar, wie ich das ganze verpacke, damit ich es an mysql_real_query() übergeben kann.
-
du übergibst den String und musst die Länge des Strings messen, du darfst den String aber an keine Funktion/Klasse übergeben, die mit 0-Terminierung arbeitet, wie zB. strlen oder std::string
-
Ich werde die ganze Geschichte per memcpy() in ein char kopieren. Und fertig.
Danke nochmal.
-
Der String den du am mysql_real_query übergibst darf schon NULL-Terminiert sein.
BLOB-Daten haben aber auch unter Umständen in den Daten selbst ein Terminierungszeichen. Deshalb wird bei mysql_query dort abgeschnitten.
Rufe einfach auf deinen String mysql_escaped_string auf und übergibt dies dann mysql_real_query. Also mach es nicht zu kompliziert. Es sit nicht kompliziert.
Grundsätzlich ist aber zu sagen, daß man immer mysql_escaped_string() aufrufen und mysql_real_query verwenden. Auch wenn man nur normale Daten an MySQL übergibt.
-
@Unix-Tom:
Ich verstehe nicht ganz, warum ich mysql_escape_string() verwenden soll? Nach dem Handbuch escapet diese Funktion den String.
Was soll ich mir darunter vorstellen? Heisst das, dass alle ** rausgenommen werden?
-
Binärdaten können beliebeige Zeichen enthalten. Das mag ein SQL-Query nicht besonders.
z.B.
SELECT * FROM tabelle WHERE name = 'O'Malley, Brian' // Funktionert nicht
Esacaped wird es dann als
SELECT * FROM tabelle WHERE name = 'O\'Malley, Brian' // Funktioniert
Genauso ist es mit Binärdaten.
-
Gut das seh ich ein. An diese Möglichkeit des Zeichens habe ich gar nicht gedacht. Danke.
Wenn ich die Daten dann später aber wieder interpretieren will, dann muss ich aber die zugefügten ** wieder entfernen, oder? Gibt es denn noch andere Zeichen, die mit einem ** versehen werden?
-
Warum musst du diese Entfernen. Sie sind doch nur für den Query drin. Escapen rufts du unmittelbar vor dem absetzen des Querys auf. Sonst musst du sogar mit den Originaldaten arbeiten da du nie wissen kannst ob escaped oder nicht. Übrigens ist dies keine Vorgehensweise von MySQl sondern im SQL-ANSI so festgeschrieben. Zwar nicht die '\' aber so ähnlich.
-
Also, ich erklär mal kurz, wie ich's zur Zeit mache. (Ich will nur vermeiden, dass wir uns irgendwo missverstehen und aneinander vorbeireden.)
Es ist so, dass ich in der Tabelle diverse Spalten habe, die mit "normalen" int-Werten gefühlt werden. Dann habe ich an den empfangenen Daten einen Block, den ich nicht zu dem Zeitpunkt interpretieren möchte und erstmal so in das Blob schreibe. Das sieht dann so aus:AnsiString QStrg; //Stringobjekt von Borland char *RestData = new char[600]; int Laenge = <Wert>; //ist bekannt //Schreiben des ersten Teils QStrg = "Insert into MyTab set C1 = " + AnsiString(Wert1) + ", C2 = " + AnsiString(Wert2) + ", Rest = '"; //Bearbeiten des zweiten Teils memcpy (RestData, &Dest, Laenge); AnsiString EscRestData; mysql_real_escape_string (hDB, &EscRestData, RestData, Laenge); QStrg += EscRestData + "'"; int Error = mysql_query (hDB, QStrg.c_str()); . . .
Ich hoffe, du schaust es dir an und berichtigst mich ggf.
Thx.
Deswegen dachte ich, ich muss zum Interpretieren später die ** wieder entfernen.
-
1. verwendest du mysql_query und nicht mysql_real_query
2. Verstehe ich nicht was du willst. Wenn du Daten in einen BLOB-Datentyp schreiben willst z.B. ein Bild dann musst du vor mysql_real_query nur mysql_escaped_string oder eben die real -version aufrufen. ich kenn AnsiString etc. nicht.Wenn du diese Daten wieder aus der DB holst musst du nichts excapen da die Daten so kommen wie sie gespeichert wurden. Da wurden die Escaped-Zeichen wieder entfernt. Das hat der SQL.Interpreter für dich gemacht. Diese hat er nur als Hilfe gebraucht.
-
Wenn ich dich jetzt richtig verstanden habe, dann soll ich erst die komplette Query zusammenstellen, dann durch mysql_real_escape_string() bearbeiten lassen und dann duch mysql_real_query() an MySql übergeben. Das habe ich jetzt gemacht und bekomme einen Syntax-Fehler zurück.
char *QStrg = new... . . //in QStrg steht dann: Insert into AS3Tab set C1 = 123, C2 = 123, RestData = '<Daten>' //Len enthält die Länge von QStrg char *EscStrg = new char [2*Len+1]; int EscStrgLen = mysql_real_escape_string (hDB, EscStrg, QStrg, Len); int Error = mysql_real_query (hDB, EscStrg, EscStrgLen); //nach Abarbeitung ist Error = -1
Wenn ich dann eine Fehlerauswertung über mysql_error() mache, dann bekomme ich
You have an error in your SQL syntax near \'<Daten>...
Deswegen habe ich nur den Teil mit den Binärdaten von mysql_real_escape_string() bearbeiten lassen und ihn dann in den anderen QueryString eingefügt. (siehe 1 Post zurück)
-
Was denn das '<Daten>'
-
<Daten> = der Block, mit den Binärdaten
Ich wollte nicht irgendwelche Symbole eintippen, also habe ich das als Synonym genommen. Tschuldige die Verwirrung.