大对象LOB(Large OBject)
用于存储二进制数据、字符数据和对文件的引用,LOB最多可以存储128TB的数据,这取决于数据库的配置。
一.理解大对象的类型
大对象类型:
- CLOB:字符LOB类型,用于存储字符数据。
- NCLOB:用于存储多字节字符数据(通常用于非英语字符)。
- BLOB:二进制LOB类型,用于存储二进制数据。
- BFILE:二进制FILE类型,用于存储指向文件的指针,这些文件可以存储于硬盘、CD等。(只有定位器存储在表中,定位器指向文件系统中存储的外部文件)
LOB由两部分组成:
- LOB定位器:一个指针,指定LOB数据的位置。
- LOB数据:存储在LOB中的实际字符或字节数据
如果数据小于4KB,就存储在表内,否则,存储在表外。
二.创建包含大对象的表
create table clob_content (
id integer primary key,
clob_column clob not null
);
create table blob_content (
id integer primary key,
blob_column blob not null
);
create table bfile_content (
id integer primary key,
bfile_column bfile not null
);
三.在SQL中使用大对象
使用CLOB和BLOB对象
1.用数据填充clob和blob对象
insert into clob_content (id, clob_column)
values(1, TO_CLOB('Creeps in this petty pace'));
insert into blob_content (id, blob_column)
values(1, TO_BLOB('100111010101011111'));
2.从clob对象检索数据
select * from clob_content;
ID CLOB_COLUMN
-----------------------------
1 Creeps in this petty pace
select * from blob_content;
ID BLOB_COLUMN
----------------------
1 100111010101011111
3.修改clob和blob对象中的数据
update clob_content
set clob_column = TO_CLOB('Hello Worlds')
where id = 1;
update blob_content
set blob_column = TO_BLOB('0A0FFB71CE90DE')
where id = 1;
使用empty_clob和empty_blob()函数来存储空对象
insert into clob_content (id, clob_column)
values(2, empty_clob());
insert into blob_content (id, blob_column)
values(2, empty_blob());
4.使用BFILE对象
注意:文件必须可以通过数据库服务器的文件系统访问
1.创建目录对象
create directory smaple_files_dir as 'c:\smaple_files';
grant read,write on directory smaple_files_dir to lob_user;
2.用文件指针填充bfile列
使用bfilename()函数包含:数据库目录的名称和文件名。
insert into bfile_content (id, bfile_column)
values(2, bfilename('smaple_files_dir', 'binarayContent.doc'));
select * from bfile_content;
ID BFILE_COLUMN
----------------------------------------------------
2 bfilename('smaple_files_dir', 'binarayContent.doc')
四.PL/SQL中使用大对象
oracle数据库自带的dbms_lob包中的方法可以使用LOB。
常用的dbms_lob中的方法:
方法 | 说明 |
---|---|
APPEND(dest_lob, src_lob) | 将从src_lob读取的数据添加到dest_lob的末尾 |
CLOSE(lob) | 关闭以前打开的LOB |
COMPARE(lob1,lob2,amount,offset1,offset2) | 比较lob1和lob2中存储的数据,lob1从offset1开始,lob2从offset2开始。偏移量始终从1开始,这是数据中第一个字符或字节的位置。比较的lob中的数据的最大字符或字节数量由amount指定 |
CONVERTTOBLOB(dest_blob, src_clob,amount,dest_offset,src_offset,blod_csid,lang_context,warning) | 将从src_clob中读取的字符数据转换为写到dest_blob中的二进制数据,src_clob从src_offset开始,dest_clob从dest_offset开始。blob_csid期望字符集,lang_context:读取的字符时使用的语境 |
CONVERTTOCLOB(dest_clob, src_blob,amount,dest_offset,src_offset,blod_csid,lang_context,warning) | 将从src_blob中读取的二进制数据转换为写到dest_blob中的字符数据 |
COPY(dest_lob,src_lob,amount,dest_offset,src_offset) | 将数据从src_lob复制到dest_lob |
CREATETEMPORARY(lob,cache,duration) | 在用户的默认临时表空间中创建临时lob |
ERASE(lob,amount,offset) | 清除lob中的数据 |
FILECLOSE(bfile) | 关闭bfile |
FILECLOSEALL() | 关闭以前打开的所有bfile |
FILEEXISTS(bfile) | 检查bfile指向的外部文件实际上是否存在 |
FILEGETNAME(bfile,directory,filename) | 返回bfile指向的外部文件所在的目录及文件名 |
FILEISOPEN(bfile) | 检查bfile当前是否处于打开状态 |
FILEOPEN(bfile, open_mode) | 以指定模式打开bfile。 |
FREETEMPORARY(lob) | 释放临时lob |
GETCHUNKSIZE(lob) | 返回读写lob中存储的数据时使用的块大小,块是数据单位 |
GET_STORAGE_LIMIT() | 返回lob的最大允许大小 |
GETLENGTH(lob) | 获得lob中存储的数据的长度 |
INSTR(lob, pattern, offset,n) | 返回lob数据中第n次出现模式匹配的字符或字节的起始位置 |
ISOPEN(lob) | 检查lob是否已经打开 |
LOADFROMFILE(dest_lob,src_bfile,amount,dest_offset,src_offset) | 将从src_bfile检索的数据加载到dest_lob |
ISTEMPORARY(lob) | 检查lob是否为临时lob |
LOADBLOBFROMFILE(dest_blob,src_bfile,amount,dest_offset,src_offset) | 将从src_bfile检索的数据加载到dest_blob |
LOADCLOBFROMFILE(dest_clob,src_bfile,amount,dest_offset,src_offset) | 将从src_bfile检索的数据加载到dest_clob |
LOBMAXSIZE | 返回lob的最大字节数(目前为2的64次方) |
OPEN(lob,open_mode) | 以指定模式打开lob |
READ(lob,amount,offset,buffer) | 从lob读取数据,并存储到buffer变量中。 |
SUBSTR(lob,amount,offset) | 返回部分lob数据 |
TRIM(lob,newlen) | 将lob数据截短到指定长度 |
WRITE(lob,amount,offset,buffer) | 将数据从buffer变量写到lob |
WRITEAPPEND(lob,amount,buffer) | 将数据从buffer变量写到lob的末尾 |
五.LONG和LONG RAW类型
- LONG:用于存储最多2GB的字符数据
- LONG RAW:用于存储醉倒2GB的二进制数据
- RAW:用于存储最多32767字节的二进制数据
1.创建
create table long_content(
id integer primary key,
long_column LONG not null
);
create table long_raw_content(
id integer primary key,
long_raw_column LONG RAW not null
);
2.向long和long raw列添加数据
insert into long_content (id, long_column)
values(1, 'Creeps in this petty pace');
insert into long_raw_content (id, long_raw_column)
values(1, '100111010101011111');
3.将long和long raw列转换为lob
使用to_lob()函数
insert into clob_content
select 10 + id, to_lob(long_column)
from long_content;
使用alter table
alter table long_content modify(long_column clob);
alter table long_raw_content modify(long_raw_column blob);
六.对大对象的增强
1.clob和nclob对象之间的隐士转换
例如:
create table nclob_content(
id integer primary key,
nclob_column nclob
);
create procedure nclob_example
as
v_clob clob := 'hello world';
v_nclob nclob;
begin
insert into nclob_content(
id,nclob_column
)values (
1,v_clob
);
select nclob_column
into v_clob
from nclob_content
where id = 1;
dbms_output.put_line(v_clob);
end nclob_example;
2.在触发器中使用lob时:new属性的用法
:new用来访问新数据
例如:
create trigger before_clob_content_update
before update
on clob_content
for each row
begin
dbms_output.put_line('clob_content change');
dbms_output.put_line(DBMS_LOB.GETLENGTH(:new.clob_column);
end before_clob_content_update;
3.加密lob数据
第一步创建电子钱包
第二步加密lob数据
create table clob_content2(
id integer primary key,
clob_column clob encrypt using 'AES128'
)lob(clob_column) store as securefile (
cache
);
第三步加密列数据
create table credit_content(
card_number number(16, 0) encrypt,
first_name varchar2(10)
);
4.压缩lob数据
create table clob_content3(
id integer primary key,
clob_column clob
)lob(clob_column) store as securefile (
compress
cache
);
5.删除lob重复数据
create table clob_content4(
id integer primary key,
clob_column clob
)lob(clob_column) store as securefile (
deduplicate lob
cache
);
6.basicfiles lob
不希望将某个lob保存为securefile lob
create table clob_content5(
id integer primary key,
clob_column clob
)lob(clob_column) store as basicfiles;