2010-06-03 76 views
10

是否可以使用sql语句搜索blob文本? 我可以从$表中选择*,其中f1类似于'%foo%',如果f1是varchar,那么f1如何是blob?任何计数器部分?oracle blob文本搜索

回答

3

如果你正在存储纯文本,它应该是一个CLOB,而不是一个BLOB,然后你仍然可以使用LIKE进行查询。 BLOB包含Oracle不知道其结构的二进制数据,因此无法以此方式进行搜索。

此工程的CLOB的任何长度(至少在甲骨文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 

需要注意的是,只有一个在6554401字节CLOB“Z” - 就在它的中间:

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

INSTR(C,'Z') 
------------ 
    3276701 
+2

@Olafur下方有个好有用的答案: http://stackoverflow.com/a/16301995/510711 – flob 2015-03-02 15:34:34

+0

这也是错误的。它只适用于<32767个字符的CLOBS。这是相当小的。 instr之类的会在这之后中断,你必须使用dbms_lob.instr来进行搜索。 – 2015-03-11 11:29:12

+0

@Olafur:你的批评是错误的,因为我已经更新了我的回答。 – 2015-03-11 12:54:24

39

这是非常可能和容易做到的。

结合使用时只需用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 
; 
+2

++当数据库不是你的时候,说模式是错误的并不是全部有用。非常感谢你为复活和回答这个问题! – Decker 2014-03-28 20:42:00

+0

这很慢,但它的工作原理,谢谢! – 2014-07-30 08:20:45

+0

这真的帮助我谢谢! – 2017-03-08 17:42:17