Insert blob in sqlite db

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Insert blob in sqlite db

    ich habe folgendes Problem:

    ich möchte ein Bild, welches ich aus einem photopicker bekomme in meine sqlite db als blob schreiben. Dazu nutze ich einmal meine db-klasse und meine hauptklasse in der ich das db-objekt aufrufe. Öffnen, schließen, strings oder änliches in die db schreiben funktioniert ohne probleme.

    db-klasse:

    Quellcode

    1. -(void)insertblob:(NSData *)blob stmt:(NSString *)blobStmnt {
    2. const char *sql = [blobStmnt UTF8String];
    3. sqlite3_prepare_v2(database, sql, 1, &statement, NULL);
    4. if (SQLITE_DONE != sqlite3_step(statement)) {
    5. NSLog(@"Error while inserting data. '%s'", sqlite3_errmsg(database));
    6. }
    7. sqlite3_bind_blob(statement, 1, [blob bytes], [blob length], SQLITE_TRANSIENT);
    8. }
    Alles anzeigen


    und hier der aufruf:

    Quellcode

    1. [database openDB:@"Content"]
    2. updateStmt = [NSString stringWithFormat:@"UPDATE Face SET image ='%@"' WHERE id='%d', image, selectedID];
    3. [database insertblob:imageData stmt:updateStmt];
    4. [database closeDB];


    ich bekomme den Fehler zurück, dass das fehlgeschlagen ist direkt beim "U" von "UPDATE"...... hmmm was mache ich falsch. jemand ne idee?
  • dritter parameter von sqlite3_prepare_v2 muss -1 sein und nicht 1 sonst nimmt er nur das erste byte (zeichen) der update-query (also das "U" das er im fehler auch angibt).
    alternativ kannst du auch die anzahl der bytes selbst angeben, da du diese aber nicht hast kannst du eben -1 übergeben und die funktion verwendet die länge bis zum null-terminator.
  • gritsch schrieb:

    hab den code jetzt gar nicht weiter angeschaut, der ist aber komplett falsch. die query ist falsch, das binden vom blob ist falsch, der step ist an der falschen stelle etc.

    google doch mal nach sample-code!

    also ich habe jetzt die ganze zeit gegoogelt und rumgesucht und probiert, aber ich checks einfach nicht. auch die sqlite seite hilft mir iwe nicht wirklich weiter. bis jetzt habe ich strings und ints wie folgt in die db geschrieben;

    Quellcode

    1. -(void)insertDatawithStmt:(NSString*)insertStmt {
    2. const char *sql = [insertStmt UTF8String];
    3. sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
    4. if(SQLITE_DONE != sqlite3_step(statement)){
    5. NSLog(@"Error while inserting data. '%s'", sqlite3_errmsg(database));
    6. }
    7. }


    diese methode habe ich dann wie folgt aufgerufen:

    Quellcode

    1. -(IBAction)saveItem:(id)sender {
    2. [database openDB:@"Content"];
    3. NSString * updateStmt = [NSString stringWithFormat:@"UPDATE DisplayMeter SET type='%@', dimensionWidth='%d', dimensionHeight='%d', dimensionRadius='%d', backgroundColor='%@', borderStyle='%@', borderWidth='%d', borderColor='%@', rotationAxisX='%d', rotationAxisY='%d' WHERE mainID='%d'", typeTextField.text, [dimensionWidthTextField.text integerValue], [dimensionHeightTextField.text integerValue], [dimensionRadiusTextField.text integerValue], backgroundHex, borderStyleTextField.text, [borderWidthTextField.text integerValue], borderHex, [rotationAxisXTextField.text integerValue], [rotationAxisYTextField.text integerValue],selectedID];
    4. //UPDATE Statement ausführen
    5. [database insertDatawithStmt:updateStmt];
    6. //DB schließen
    7. [database closeDB];


    das funktioniert wunderbar. Ich seh den schlauch nicht auf dme ich stehe ^^
  • OUCH, OUCH, OUCH.

    bewusste und unbewusste SQL-Injection lässt grüßen!

    wenn du nur eine query ausführen willst dann brauchst du kein prepare und step und finalize (das du komplett vergisst) sondern kannst direkt sqlite3_exec verwenden. du musst dann aber SQL-Injections manuell verhindern.

    wenn du über prepare und step gehen willst dann musst du 1 mal prepare aufrufen, dann für jede row jeweils für jeden parameter ein bind, dann für jede row ein step, und ein rest. und gaz zum schluss noch das finalize.
  • Bilder gehören nicht in eine SQL DB Basta! Das kannst du mal als gegeben ansehen. Und wenn du einen Grund hast, dann ist der Käse.

    Ich würde Dir anraten ein gutes mySQL Buch zu kaufen und mal die Grundlagen zu lernen.

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Bilder gehören nicht in eine SQL DB Basta! Das kannst du mal als gegeben ansehen. Und wenn du einen Grund hast, dann ist der Käse.

    Ich würde Dir anraten ein gutes mySQL Buch zu kaufen und mal die Grundlagen zu lernen.

    Claus


    wenns keinen speziellen grund gibt, würd ich bilder auch nciht in die DB schreiben, aber gehen wir einfach mal von "daten" aus - egal was es ist.

    naja, ein buch zu mysql wird ihm wenig helfen bezüglich sqlite ;)
  • Um auf das Thema zurückzukommen. Ich habe mitlerweile viele Dinge probiert, aber ich komme mit dem bind-befehl denke ich einfach nicht klar.


    Quellcode

    1. int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

    Quellcode

    1. sqlite3_bind_blob(statement, 1, [blob bytes], [blob length], SQLITE_TRANSIENT);


    also statement ist ja ein pointer auf ein sqlite_stmt welches ich von sqlite3_prepare_v2() zurück bekomme.
    das 2. Argument die 1, der index des sql parameters.
    dann kommt der 3. das ist der wer an den gebindet wird
    das 4. anzahl der bytes ( länge)
    dann der destruktor.

    also ich checke nicht was ich falsch mache. wenn kann ja nur das statement falsch sein.
  • macmoonshine schrieb:

    Thallius schrieb:

    Bilder gehören nicht in eine SQL DB Basta! Das kannst du mal als gegeben ansehen. Und wenn du einen Grund hast, dann ist der Käse.

    Das kann man doch so pauschal nicht sagen. Ob das sinnvoll ist, hängt doch vom Anwendungsfall ab.


    Ich wüßte nur keinen einzigen Fall, wo es von Vorteil wäre die Daten direkt in die DB zu schreiben. Das bläht die DB auf und macht sie unnötig langsam. Von einem OPTIMIZE TABLE mal ganz abgesehen. Da kann man dann wahrscheinlich Urlaub beantragen und nach dem Urlaub ist der fertig.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Ich wüßte nur keinen einzigen Fall, wo es von Vorteil wäre die Daten direkt in die DB zu schreiben.

    Ich kenne einige Anwendungen, wo das sinnvoll ist.

    Thallius schrieb:

    Das bläht die DB auf und macht sie unnötig langsam.

    Habe ich noch nicht feststellen können. Abgesehen davon kann das bei einem Dateisystem mit vielen Dateien auch leicht passieren.

    Thallius schrieb:

    Von einem OPTIMIZE TABLE mal ganz abgesehen. Da kann man dann wahrscheinlich Urlaub beantragen und nach dem Urlaub ist der fertig.

    Glücklicherweise gibt es ja nicht nur MySQL.
    „Meine Komplikation hatte eine Komplikation.“
  • UPDATE:

    Ich hab mal ein paar sachen geändert.

    Quellcode

    1. -(void)insertblob:(NSData *)blob stmt:(NSString *)blobStmnt {
    2. const char *sql = [blobStmnt UTF8String];
    3. sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
    4. int returnValue = sqlite3_bind_blob(statement, 1, [blob bytes], [blob length], SQLITE_TRANSIENT);
    5. if (returnValue != SQLITE_OK) {
    6. NSLog(@"NOT OK");
    7. }
    8. }


    und das statement so

    Quellcode

    1. updateStmt = [NSString stringWithFormat:@"UPDATE Face SET image =? WHERE id='%d'",selectedID];
    2. [database insertblob:imageData stmt:updateStmt];


    aber ich bekomme immer noch nicht das ergebnis was ich haben will. anscheinen schreibt der das nicht in die db. hmm
  • OMG ja scheisse ich hab step und finaliza weiter unten auskommentiert. jetzt gehts also hier meine lösung:

    Quellcode

    1. -(void)insertblob:(NSData *)blob stmt:(NSString *)blobStmnt {
    2. NSLog(@"stmt:%@",blobStmnt);
    3. const char *sql = [blobStmnt UTF8String];
    4. NSLog(@"intlengh:%d", [blob length]);
    5. sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
    6. int returnValue = sqlite3_bind_blob(statement, 1, [blob bytes], [blob length], SQLITE_TRANSIENT);
    7. sqlite3_step(statement);
    8. sqlite3_finalize(statement);
    9. if (returnValue != SQLITE_OK) {
    10. NSLog(@"NOT OK");
    11. }
    12. }
    Alles anzeigen


    da kommen jetzt noch errormessages rein als nslog, aber die funktionalität geht damit.

    DANKE DIR!!!!