текстовый поиск оракул блоб - PullRequest
15 голосов
/ 03 июня 2010

Можно ли искать текст блоба с помощью оператора sql? Я могу выбрать select * from $ table, где f1 похож на '% foo%', если f1 - это varchar, как насчет f1 - это блоб? Любая контраргумент для этого?

Ответы [ 4 ]

57 голосов
/ 30 апреля 2013

Это вполне возможно и легко сделать.

Просто используйте dbms_lob.instr вместе с utl_raw.cast_to_raw

Так что в вашем случае, если t1 является BLOB, выбор будет выглядеть так:

select *
  from table1
 where dbms_lob.instr (t1, -- the blob
                   utl_raw.cast_to_raw ('foo'), -- the search string cast to raw
                   1, -- where to start. i.e. offset
                   1 -- Which occurrance i.e. 1=first
                    ) > 0 -- location of occurrence. Here I don't care.  Just find any
;
4 голосов
/ 04 июня 2010

Если это документ Word или PDF, посмотрите Oracle Text .

4 голосов
/ 03 июня 2010

Если вы храните простой текст, это должен быть CLOB, а не BLOB, и тогда вы все равно можете делать запросы, используя LIKE. Большой двоичный объект содержит двоичные данные, структура которых Oracle не знает, поэтому он не может искать их таким образом.

Это работает для CLOB любой длины (по крайней мере, в Oracle 12C):

SQL> create table t1 (c clob);

Table created.

SQL> declare
  2     x clob;
  3  begin
  4     for i in 1..100 loop
  5        x := x || rpad('x', 32767, 'x');
  6     end loop;
  7     x := x || 'z';
  8     for i in 1..100 loop
  9        x := x || rpad('x', 32767, 'x');
 10     end loop;
 11     insert into t1 values (x);
 12  end;
 13  /

PL/SQL procedure successfully completed.

SQL> select dbms_Lob.getlength(c) from t1 where c like '%z%';

DBMS_LOB.GETLENGTH(C)
---------------------
              6553401

Обратите внимание, что в этом 6555401 байтовом CLOB есть только один 'z' - прямо в середине:

SQL> select instr(c, 'z') from t1;

INSTR(C,'Z')
------------
     3276701
0 голосов
/ 12 июня 2019

приведенный ниже код отображает детали из BLOB-объекта в виде текста с использованием функции UTL_RAW.CAST_TO_VARCHAR2 , затем мы используем функцию substr , чтобы вырезать текст от начала ожидаемых данных до конца. тем не менее, вы можете использовать instr function , LENGTH function , если вы знаете расположение данных, которые вы ищете

select NVL(SUBSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), 
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '<ns:xml_element>') + LENGTH('<ns:xml_element>'),
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '</ns:xml_element>') - (
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '<ns:xml_element>') + LENGTH('<ns:xml_element>'))),
    utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(blob_body))
    ) blob_body
from dual 
where SUBSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), 
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '<ns:xml_element>') + LENGTH('<ns:xml_element>'),
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '</ns:xml_element>') - (
INSTR(UTL_RAW.CAST_TO_VARCHAR2(blob_body), '<ns:xml_element>') + LENGTH('<ns:xml_element>'))) like '%foo%';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...