insert von BLOB in interbase



  • Ich muß in eine Tabelle mit einem SQL-Statement ein BLOB einfügen.
    Zum testen habe ich mir erstmal eine Tabelle angelegt mit einem Feld Nummer und einem weiteren Beschreibung (BLOB).

    Über eine Query gebe ich als SQL-Anweisung "Insert into ARTIKEL VALUES (:NR, :BEschreibung)" ein.
    Zur Laufzeit dann noch das:

    Query2->Params->Items[0]->AsInteger = 40000;
      Query2->ParamByName("Beschreibung")->AsMemo = DBMemo1->Text;
      Query2->ExecSQL();
    

    Funktioniert auch alles.

    Ich muß allerdings meinem Programm die Insert-Anweisung erstmal ohne Query durchführen.
    Mein Versuch ist so:

    TBlobField* MyBlob = dynamic_cast <TBlobField*>
                                 (IBTable->FieldByName("BEMERKUNG"));
          MyBlob->SetFieldType(ftMemo);
          MyBlob->AsString = MainForm->TableMain->FieldByName("BEMERK1")->AsString +
                         MainForm->TableMain->FieldByName("BEMERK2")->AsString;
    
          Buf = Format("INSERT INTO %s (NUMMER, ART, BEZEICHNUNG, BEMERKUNG, \
                        PRODUKTIONSMENGE, ERSTELLT, DATUM, \
                        MISCHUNGSANZAHL ) \
                        VALUES (%s, %s, '%s', '%s', %s, '%s', '%s', '%s', %s",
            ARRAYOFCONST(("REZEPT",
                        MainForm->TableMain->FieldByName("REZNUMMER")->AsString,
                        MainForm->TableMain->FieldByName("REZART")->AsString,
                        MainForm->TableMain->FieldByName("REZBEZEICH")->AsString,
                        MyBlob,
                        PMenge,
                        MainForm->TableMain->FieldByName("ERSTELLT")->AsString,
                        MainForm->TableMain->FieldByName("REZDATUM")->AsString,
                        Manz)));
    

    Leider funktioniert das nicht so einfach.
    Wie übergebe ich also BLOBs einer SQL-Anweisung?



  • a) "Funktioniert nicht" ist keine ausreichende Problembeschreibung.
    b) Zum Thema BLOB liefert die Suchfunktion etliche Threads, die hast du alle durch?



  • Jansen schrieb:

    a) "Funktioniert nicht" ist keine ausreichende Problembeschreibung.

    Stimmt. war eine schlechte Fehlerbeschreibung.
    Ich habe dann jedesmal NULL in dem entsprechenden Feld bzw. wenn ich mir den Insert-String schon ansehe, steht an dieser Stelle für den Wert ",,".

    Jansen schrieb:

    b) Zum Thema BLOB liefert die Suchfunktion etliche Threads, die hast du alle durch?

    Jawohl. Sonst hätte ich mich erst gar nicht gewagt zu posten. 😉
    Sowohl hier als auch:
    1. in der FAQ
    2. bei google.groups
    3. im gesamten Netz.
    4. in der Interbase-Doku
    5. in der Borland-Hilfe

    Für das was ich suche habe ich auch nicht nur annähernd ein Beispiel gefunden.
    Fast immer waren es selects und keine inserts. Aber auch bei denen konnte ich nichts abkupfern.



  • aheim,

    aheim schrieb:

    Ich muß allerdings meinem Programm die Insert-Anweisung erstmal ohne Query durchführen ...

    Dieser Satz ist grammatisch recht irreführend und erschwert dem geneigten Leser die Analyse Deines Problems. Was meinst Du vor allem mit "ohne Query durchführen"??
    Hier also meine Vermutung: Der Parameter "MyBlob" in Deinem "ARRAYOFCONST"-Aufruf ist kein String, sondern ein TBlobField-Zeiger.
    Hast Du schon einmal einen Blick auf Dein SQL-Statement geworfen, bevor Du es an den Server schickst? Steht da der Text, den Du in das Blob-Feld schreiben willst, wirklich drin?



  • Mit dem irreführend stimmt. Habe beim Schreiben auch gedacht, daß es nicht so leicht verständlich ist. Dabei habe ich aber an den Inhalt gedacht und mir nicht den Müll angesehen, den ich da geschrieben hatte.
    So hätte dieser Satz lauten sollen:
    "Ich muß allerdings in meinem Programm die Insert-Anweisung erstmal ohne TQuery durchführen"

    Hast Du schon einmal einen Blick auf Dein SQL-Statement geworfen, bevor Du es an den Server schickst? Steht da der Text, den Du in das Blob-Feld schreiben willst, wirklich drin?

    Eben nicht. Es steht im Statement "abc,,xyz". D.h. vor und hinter dem Blob war alles in Ordnung. Ich hatte gedacht, statt des Blobs vielleicht nur den Inhalt (string) dorthin zu schreiben.

    Hierbei wäre das mögicherweise aber noch gegangen. Ich muß aber noch weitere Felder ändern, die dann kein String sondern binär sind. Daher hatte ich eine "leichte" Möglichkeit gesucht BLOBs einzufügen.

    Hier nochmal kurz zum Verständnis:

    Ich habe mir in Interbase eine Datenbank und Tabellen über den direkten Aufruf der BDE-Funktionen erzeugt
    Check(DbiQExecDirect(IBDB->Handle, qrylangSQL, Buf.c_str(), NULL));

    Anschliessend wurden sämtliche Daten aus den dbase-Tabellen ausgelesen und in die Datenbank importiert.
    Dies ging alles wunderbar über DbiQExecDirect.
    Jetzt wurden zwei Felder zu einem BLOB zusammengefügt.
    Hatte hier einen Gedankenfehler. Habe gedacht ich müßte jetzt für jede Tabelle eine Query anlegen wenn ich es mit Parametern erledigen will.
    Also war mein Gedanke, den BLOB auch über ein SQL-Statement einzufügen.

    Habe heute morgen nochmals intensiv gesucht.
    Ein BLOB über direkte SQL-Anweisung einzufügen geht nicht.
    Es gibt 2 andere Möglichkeiten.
    1. Über die API-Funktionen von Interbase. Sind im APi-Guide beschrieben.
    (war mir dann viel zu viel Arbeit)
    2. Über eine Query mit Params.

    Habe jetzt die 2 problematischen Tabellen mit Querys gemacht. Allerdings mit einer einzigen der ich zur Laufzeit die Parameter zuweisen. Hatte ich vergessen, dass das geht.
    Der Nachteil ist, daß es langsamer als über die Query geht. Aber man kann nicht alles haben.

    Ich vermute mal, dass es auch über den direkten Aufruf der BDE-Funktionen geht.

    Hoffe mal, daß es jetzt alles einigermaßen verständlich ist.
    Sorry nochmal für die halben Erklärungen. Lag bis gestern krank im Bett. Der Kopf ist noch nicht so ganz arbeitsfähig. Grund war nicht irgendwelche Trinkgelage (direkt zur Vorbeugung 😉 ).
    Trotzdem nochmal danke für Eure Bemühungen.



  • aheim,

    irgendwo habe ich das hier aufgeschnappt: "INSERT CURSOR (BLOB)"
    Vieleicht stellt das irgendwie eine Lösung dar.
    Und das hier sieht wie eine Variante einer Häppchen-weisen Speicherung aus.

    Als letzten Ausweg könntest Du noch die binären Daten in ein Text-Format (z.B. Base64) umwandeln und in dieser Form in das SQL-Statement stecken. Ich weiß allerdings nicht, ob es eine Begrenzung für die Größe eine SQL-Statements in Interbase gibt bzw. wie hoch diese ist.



  • Danke. Hatte ich nicht gefunden.
    Ist so ähnlich wie ich es jetzt mache.
    Nur mit Cursorn kenne ich mich nicht mehr so aus. Habe ich vor mehreren Jahren mal gemacht unter Informix und Unix.

    Allerdings war mein erster Ansatz, das ganze ohne eine Query zu machen. Geht aber eben nicht.

    Jetzt mache ich es so:

    Buf = "INSERT INTO KUNDEN (NUMMER, NAME1, NAME2, NAME3, STRASSE,\
                         POSTFACH, LAENDER, PLZ, ORT, BEZIRK, TELEFON, TELEFAX,\
                         BEMERKUNG) \
                 VALUES (:NUMMER, :NAME1, :NAME2, :NAME3, :STRASSE,\
                         :POSTFACH, :LAENDER, :PLZ, :ORT :BEZIRK, :TELEFON, :TELEFAX,\
                         :BEMERKUNG);";
          Query1->SQL->Add(Buf);
          Query1->ParamByName("NUMMER")->AsString =
                        MainForm->TableMain->FieldByName("KUNUMMER")->AsString;
    
          // .... Rest weggelassen zur Vereinfachung
    
          Query1->ParamByName("BEMERKUNG")->AsBlob =
                        MainForm->TableMain->FieldByName("BEMERK1")->AsString +
                        "\n\r" +
                        MainForm->TableMain->FieldByName("BEMERK2")->AsString;
    

    Trotzdem nochmal danke. Den Tip mit dem Cursor werde ich mir auf jeden Fall mal abspeichern. Man kann ja nie wissen.


Anmelden zum Antworten