Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Inhalt eines Blobfeldes nur bei Abruf laden (https://www.delphipraxis.net/112609-inhalt-eines-blobfeldes-nur-bei-abruf-laden.html)

Moony 24. Apr 2008 10:35

Datenbank: Oracle • Zugriff über: ODAC oder ADO

Inhalt eines Blobfeldes nur bei Abruf laden
 
Hallo zusammen,

folgende Situation ist gegeben:

Ich greife über die ODAC oder ADO Komponente auf einen Oracle Server zu, indem eine SQL Anweisung ausgeführt wird (SELECT * FROM Table). In dieser Tabelle ist mindestens ein Blobfeld vorhanden. Je nachdem wie viele Daten jedes Blobfeld enthält, dauert die Übertragung sehr lange (ca. 5-10 Minuten) bis das Query die Datensätze in das DBGrid lädt.

Meine Frage an dieser Stelle ist:
Gibt es eine Möglihckeit zwar alle Felder der Datenbank zu holen, aber beim Inhalt des Blobfeldes eine Ausschlußklausel zu setzen, so dass die Inhalte der Blobfelder explizit bei direktem Abruf des Datensatzes erfolgen? Somit würde sich die Dauer der Datenübertragung um 90% verringern.

Danke & Gruß, Moony

mkinzler 24. Apr 2008 10:46

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Sollte bei Oracle eigentlich automatisch so sein, da die Blobs separat von der Tabelle gespeichert werden.
Du könntest das Blob-Feld als Dummy holen.

Moony 24. Apr 2008 10:50

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Und wie soll das gehen?

Wie gesagt, ich führe eine normale SQL Anweisung aus, dennoch braucht das Query so lange, um die Tabelle abzurufen.

mkinzler 24. Apr 2008 10:55

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Versuch mal
SQL-Code:
SELECT <So. Felder>, CAST( null as BLOB) as <Blobfeldname> from <Tabelle>;

Moony 24. Apr 2008 11:02

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Diese Abfrage setzt aber voraus, dass ich alle Feldnamen kenne und auch weiß welche Felder Blobfelder sind? Ist das richtig?

mkinzler 24. Apr 2008 11:10

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Ja. Aber ich würde mal in den Komponenten schauen, ob man das automatische Fetchen der Blobs unterbinden kann (wenn es wirklich das Problem ist)

Bernhard Geyer 24. Apr 2008 11:14

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Erst

SQL-Code:
SELECT * from <Tabelle> where 1=2;
Um Felder + Feldtypen zu bekommen
und dann nur alle Nicht-Blob-Felder abfragen.

Moony 24. Apr 2008 11:45

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Also, ich habs jetzt folgendermaßen gemacht:

Delphi-Quellcode:
  OraQuery1.Close;
  OraQuery1.SQL.Clear;
  SQL := 'SELECT * FROM ' + mytable + ' WHERE 1=2';
  OraQuery1.SQL.Add(SQL);
  OraQuery1.Open;
  Lst       := TStringList.Create;
  LstBlob   := TStringList.Create;
  LstNonBlob := TStringList.Create;
  try
    OraQuery1.GetFieldNames(Lst);
   
    for i := 0 to Lst.Count - 1 do
    begin
      if OraQuery1.FieldByName(Lst.Strings[i]).IsBlob then
        LstBlob.Add(Lst.Strings[i])
      else LstNonBlob.Add(Lst.Strings[i]);
    end;

    SQL := 'SELECT ' + LstNonBlob.CommaText + ',';

    for i := 0 to LstBlob.Count - 1 do
    begin
      SQL := SQL + 'CAST(NULL AS BLOB) AS ' + LstBlob.Strings[i];

      if i < (LstBlob.Count - 1) then
         SQL := SQL + ',';
    end;

    SQL := SQL + ' FROM ' + mytable;

    OraQuery1.Close;
    OraQuery1.SQL.Clear;
    OraQuery1.SQL.Add(SQL);
    OraQuery1.Open;
  finally
    Lst.Free;
    LstBlob.Free;
    LstNonBlob.Free;
  end;
Wenn ich das Query dann öffnen möchte gibts folgende Fehlermeldung:

"ORA-00932: inconsistent datatypes:expected- got BLOB"

hoika 24. Apr 2008 12:11

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Hallo,

hast du mal <SQL> vor dem Open angesehen ?
Wenn z.B. gar kein Blob in der Tabelle ist,
steht da

select x,y, from Table.

Das letzte Komma ist falsch.



Heiko

Moony 24. Apr 2008 12:17

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
@hoika:
Das stimmt wiederum. Das werde ich ändern. Aber das ist nicht die Ursache, weil ich weiß dass 1 Feld definitv ein Blobfeld ist.

@mkinzler:
Das ist das Problem! Die Bilddaten werden bei dem SQL String mitgeladen, was völlig unnötig ist. Das frißt nur jede Menge Performance und Zeit die Tabelle überhaupt angezeigt zu bekommen. Das einzige was ich einstellen kann ist, ob ich alle oder nur eingeschränkt die Datensätze lade. Nichts desto trotz lädt er bei eingeschränkten Datensätzen ebenfalls die Blobdaten mit. Deshalb brauche ich eine Möglichkeit in der SQL-Anweisung, um sagen zu können, dass ich zwar alle Felder haben möchte, aber die Blobdaten nur dann abgerufen werden, wenn ich sie wirklich benötige.

Olli73 25. Apr 2008 13:13

Re: Inhalt eines Blobfeldes nur bei Abruf laden
 
Prüf mal bei den ODAC-Komponenten folgende Einstellungen:

TOraDataSet.OptionsDS ->

CacheLobs
If True (default value) then local memory buffer is allocated to hold a copy of the Lob content. See notes below for further details.

DeferredLobRead
If True then all Oracle 8 Lob values are only fetched when they are explicitly requested. Otherwise entire record set with any Lob values is returned when dataset is opened. Whether Lob values are cached locally to be reused later or not is controlled by CacheLobs option.

Notes:
CacheLobs option controls the way Lob objects are handled while the application fetches records from the database. Setting CacheLobs to False may bring up the following benefits for time-critical applications: reduced traffic over the network since Lob objects are only transferred on demand; less memory is needed on the client side because returned record sets do not hold contents of Lob fields. Actual value for the Lob field is passed to the client only when a data-aware control requests it.

Gruß,
Olli


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz