![]() |
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 |
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. |
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. |
Re: Inhalt eines Blobfeldes nur bei Abruf laden
Versuch mal
SQL-Code:
SELECT <So. Felder>, CAST( null as BLOB) as <Blobfeldname> from <Tabelle>;
|
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?
|
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)
|
Re: Inhalt eines Blobfeldes nur bei Abruf laden
Erst
SQL-Code:
Um Felder + Feldtypen zu bekommen
SELECT * from <Tabelle> where 1=2;
und dann nur alle Nicht-Blob-Felder abfragen. |
Re: Inhalt eines Blobfeldes nur bei Abruf laden
Also, ich habs jetzt folgendermaßen gemacht:
Delphi-Quellcode:
Wenn ich das Query dann öffnen möchte gibts folgende Fehlermeldung:
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; "ORA-00932: inconsistent datatypes:expected- got BLOB" |
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 |
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. |
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 13:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz