Announcement

Collapse
No announcement yet.

Text-BLOB in MSSQL7 ohne ADOExpress

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Text-BLOB in MSSQL7 ohne ADOExpress

    Hallo,<BR>
    <BR>
    Ich versuche verzweifelt über reines ADO Text-Dokumente in ein BLOB-Feld eines MSSQL Servers zu bringen.<BR>
    Das BLOB-Feld ist als data type "Text" deklariert.<BR>
    Ich kann, dank der vielen Beispiele hier im Forum, ohne Probleme BLOB's vom Typ Image beschreiben und wieder auslesen. Aber wenn ich etwas ähnliches für Text-BLOB's mache, geht's schief.<BR>
    Mein Programm sieht so aus (Der einzige Unterschied zu Image BLOB's ist die Deklaration des Stream-Typs als adTypeText.Ich habe aber schon alles mögliche andere auch ausprobiert):<BR>
    <BR>
    try<BR>
    //Stream initialisieren:<BR>
    ADOStream:=coStream.Create;<BR>
    ADOStream.Type_:=adTypeText; <--- Ich denke ich brauche das wegen Text-BLOB. adTypeBinary geht jedenfalls auch schief<BR>
    ADOStream.Open(EmptyParam,adModeUnknown,adOpenStre amUnspecified,'','');<BR>
    ADOStream.LoadFromFile(OpenDialog1.FileName);<BR>
    //Leeres Recordset-Objekt erzeugen:<BR>
    OleCheck(coCreateInstance(CLASS_RecordSet, nil, CLSCTX_ALL, IID__RecordSet, RecordSet));<BR>
    RecordSet.CursorLocation:=adUseClient;<BR>
    RecordSet.Open('SELECT * FROM Tabelle1',ConnString, adOpenStatic, adLockOptimistic, adCmdText);<BR>
    //Einfügen:<BR>
    RecordSet.Fields[4].Value:=ADOStream.Read(adReadAll);<BR>
    RecordSet.Update(EmptyParam,EmptyParam);<BR>
    finally<BR>
    ADOStream.Close;<BR>
    ADOStream:=nil;<BR>
    RecordSet.Close;<BR>
    RecordSet:=nil;<BR>
    end;<BR>
    <BR>
    Die Fehlermeldung lautet: "Der Vorgang ist in diesem Zusammenhang nicht zugelassen" wenn der Stream gelesen werden soll ("RecordSet.Fields[4].Value:=ADOStream.Read(adReadAll);").<BR>
    <BR>
    Wer kann mir meinen Denkfehler zeigen?<BR>
    Zur Not könnte ich die Text-Dokumente natürlich auch in Image-Felder stecken, aber wenn der SQL Server schon Text anbietet, möchte ich es eigentlich auch verwenden.<BR>
    <BR><BR>
    Vielen Dank im Voraus,<BR>
    <BR>
    Peter

  • #2
    Hallo,

    in meinem (funktionierenden) Stream-Beispiel verwende ich an 2 Stellen eine andere Implementierung: <br>
    1. Über die WHERE-Einschränkung <i>WHERE 1 = 0</i> sorge ich beim SELECT dafür, dass garantiert eine leere Ergebnismenge mit der Tabellenstruktur zurückkommt. <br>
    2. Vor dem Zuweisen des BLObs fordere ich über <i>Recordset.AddNew(EmptyParam, EmptyParam)</i> einen neuen (leeren) Datensatzpuffer an

    Comment


    • #3
      Hallo,<BR>
      <BR>
      Ich möchte die Text-Datei jedoch in einen bestehenden Record einfügen.<BR>
      Aus diesem Grund verwende ich nicht WHERE 1=0 und auch keinen neuen (leeren) Datensatzpuffer.<BR>
      Wobei ich in meinem Beispiel von oben etwas vergessen habe:<BR>
      Ich bewege mich in meinem Recordset via "Recordset.Move(Anzahl,EmptyParam)" vor dem Aufruf von "RecordSet.Fields[4].Value:=ADOStream.Read(adReadAll);" zuerst zu dem Eintrag im Recordset den ich bearbeiten möchte (Ich weiß das diese Vorgehensweise keine besonders gute Performance hat. Das wird in der endgültigen Version auch noch geändert. Aber jetzt zum Testen war es für mich am einfachsten).<BR>
      <BR>
      Exakt diese Vorgehensweise funktioniert ja auch einwandfrei für Image-Blob Felder. Wo ist jetzt der Unterschied zu Text-Blob Feldern? Oder ist ein MSSQL Text-Feld gar kein "echtes" BLOB-Feld für Text-Dateien?<BR>
      Bei InterBase habe ich es jedenfalls immer so gehandhabt. Ich bein einfach stilschweigend davon ausgegangen, daß MSSQL (zumindest an dieser Stelle) genauso funktioniert.<BR>
      <BR>
      Pete

      Comment


      • #4
        Hallo,

        der Microsoft SQL Server kann 2.147.483.647 Zeichen in einer text-Spalte speichern. Das Problem liegt (je nach Delphi-Version) vermutlich in einem Delphi-Bug. Mit dem folgenden Aufruf ist mit Delphi 6 (und installiertem UpdatePack#1) der Update mit Memo-Daten in eine text-Spalte der Tabelle erfolgreich:
        <pre>
        {

        CREATE TABLE StreamBLOBDemo (
        ID int NOT NULL CONSTRAINT PK_StreamBLOBTest PRIMARY KEY,
        FileContents text)

        }

        procedure TForm1.ToolButtonBLOBClick(Sender: TObject);
        var
        aRS : _RecordSet;
        vSQL : OleVariant;
        swText : WideString;
        begin
        aRS := CoRecordset.Create;
        aRS.CursorLocation := adUseClient;
        vSQL := 'SELECT ID, FileContents FROM StreamBLOBDemo';
        aRS.Open(vSQL, ADOConnection1.ConnectionObject,
        adOpenStatic, adLockOptimistic, adCmdText);
        aRS.Fields[1].Value := MemoLog.Text;
        aRS.Update(EmptyParam, EmptyParam);
        aRS.Close;
        // Anzeige aktualisieren
        ADODataSet1.Active := False;
        ADODataSet1.Active := True;
        end;
        </pre>
        Ich würde an Ihrer Stelle das Projekt mit Debug-DCUs compilieren und dann schrittweise durch die Delphi-Units debuggen, bis der Übeltäter (vermutlich _VarFromWStr) erreicht wird

        Comment


        • #5
          Vielen Dank,<BR>
          <BR>
          Mit dem Umweg über das Memofeld, dafür ohne Stream, funktioniert es einwandfrei.<BR>
          Und zwar sogar ohne Update-Pack !<BR>
          <BR><BR>
          Nochmals Herzlichen Dank,<BR>
          <BR>
          Pete

          Comment

          Working...
          X