2017-05-03 16 views
5

Piszę zapytanie o narzędzie do raportowania (projektant raportów Pentaho), w którym muszę pobrać pliki jpg, które są przechowywane w bazie danych Oracle 11. Sztuczka polega na tym, że jogs (przechowywany jako BLOBy) zawiera 12-bajtowy nagłówek (dodany przez inną aplikację), który muszę usunąć. Narzędzie do raportowania wymaga również, aby dane były zwracane jako dane RAW.Oracle SQL - Jak usunąć wiodące bajty z BLOB (i wrócić jako RAW)?

Występują problemy, w których wydaje się, że funkcje/procedury, które znalazłem do manipulowania obiektami BLOB, mają restrykcyjne ograniczenia rozmiaru/długości.

To zapytanie jest tak blisko do pracy, jak mogę dostać, używając DBMS_LOB.SUBSTR (dbfile.filedata, 2000,12):

select DBMS_LOB.SUBSTR(dbfile.filedata,2000,12) as filedata 
from bms_0002005_251 safety 
inner join bms_9999999_100 file02 on safety.bms_id = file02.bms_fk_0002005_839_ID 
inner join bms_9999999_104 inc on safety.bms_fk_0002005_844_id = inc.bms_id 
left join bms_dbfiles dbfile on file02.bms_9999999_40 = dbfile.uniqueid 

przypadku obrazów < = 2000 bajtów, to działa doskonale, paski nagłówek 12 bajtów i zwraca dane surowe jak FFD8FFE000104A46494600010201006000600000FFEE000E41646F626500640000000001 ... itd

ale dla większych obrazów (większość obrazów) 2000 nie wystarczy, ale tak szybko, jak zwiększyć długość podciągu do 2001, kwerenda nie powiedzie:

ORA-06502: PL/SQL: numeric or value error: raw variable length too long ORA-06512: at line 1 06502. 00000 - "PL/SQL: numeric or value error%s"

To jest najbliższy, ale mam długą historię - czy jest jakiś sposób w jednym zapytaniu, czy mogę usunąć pierwsze 12 bajtów z dużego BLOBa i zwrócić dane jako RAW?

+1

Obawiam się, że musisz wymyślić rozwiązanie poza bazą danych Oracle. Wiesz, RAW naprawdę * jest * ograniczony do maksymalnej długości 4000 (w kontekście SQL) lub 32767 (w kontekście PLSQL), więc BLOB jest tym, czego powinieneś używać do wysyłania plików JPEG z BLOB do twojej aplikacji wywołującej. Nawet jeśli zmienisz swoją zmienną po stronie klienta na RAW (32767), w końcu będziesz miał problemy z plikami JPEG o długości ponad 32 tys. – nop77svk

+0

Dziękuję za info @ nop77svk - a co jeśli postanowię wyjść z RAW z równania ... czy istnieje sposób na zwrócenie całego BLOB minus pierwsze 12 bajtów? – whitegoose

+0

Tak, jest. Wywołane przez ciebie 'dbms_lob.substr()' jest właściwą drogą. – nop77svk

Odpowiedz

0

Ogólnie rzecz biorąc, nie można modyfikować obiektu typu "blob" w zapytaniu, biorąc pod uwagę ORA-14553. Zmienna Blob to wskaźnik do danych, ale nie same dane. Dlatego funkcje takie jaknie zwracają wartości BLOB lub CLOB, ale RAW lub CHAR - ponieważ dane (zmienne) ostatnich typów są bezpośrednio dostępne w pamięci RAM.

Tak więc, aby wysłać zapytanie o zmodyfikowany obiekt typu blob (z 12 bajtami odciętymi od głowy), musimy utworzyć i zapisać zmodyfikowany obiekt typu blob przed wysłaniem zapytania. W zależności od wymagań biznesowych można to zrobić na miejscu lub tworząc nowe obiekty blob, zachowując oryginały. W przypadku pytania przypuszczam, że nie możemy modyfikować oryginalnych obiektów blob w miejscu.

Oczywiście, drugi sposób (zachowanie oryginałów) jest bardziej zasobochłonny.

Duży obraz rozwiązanie:

  1. Ustal listę bąble idziesz do kwerendy
  2. Dla każdej pozycji na liście tworzyć i przechowywać zmodyfikowany blob (npz przyciętymi 12 bajtów) ze związku o id oryginalnego zapytania
  3. uruchomić powracających zmodyfikowanych bąble
  4. Usuwanie modyfikacji plamy (bezpośrednio aftery kursor zapytania zużyte lub zgodnie z harmonogramem)

Powoduje więcej problemów niż rozwiązuje:

  • potrzeba oczyszczania modyfikowanych bąble
  • synchronizacja oryginalne i modyfikowane
  • podwojenie AM ount przechowywanych danych
  • kolejne niespodzianki

Chyba nie jest mniej bolesne rozwiązanie - napisać kod w zewnętrznej partii spożywania wyniki kwerendy i modyfikować dane blob ouside bazy.

Powiązane problemy