VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

兼容BFILE数据类型

功能描述

bfile用于存储操作系统中的物理文件数据对象。

bfilename函数返回一个bfile文件定位器,该定位器指向操作系统中一个物理文件。

功能说明

1、bfilename函数主要用于bfile类型数据的构造,构造的数据源为一个directory对象和一个操作系统物理文件名。以下为这两部分的说明:

(1)directory对象。必须在
bfilename函数调用前创建,并且对象名区分大小写。

(2)文件名。操作系统上一个物理文件,由于bfile为只读数据类型,必须在访问文件数据前创建该文件。

2、bfile数据类型主要用于对
bfilename函数构造的数据进行存储,然后调用dbms_lob内置包的接口对该数据进行操作。bfile数据类型的功能主要分为三个部分:

(1)bfile数据的存储和打印

(2)bfile数据的使用,主要为对操作系统物理文件的读取过程,即分为以下三部分:

①
打开操作系统物理文件。bfile为只读数据类型,因此打开文件的模式只能为只读。

②
对文件进行读取。可根据参数设置来决定读取文件的字节数,如需读取整个文件,可先调用dbms_lob包的getlength,函数获取文件的大小。需注意的是,单次读取文件的字节数不能超过32767字节,如文件过大,可通过设置参数对文件进行多次读取。

③ 关闭文件。对打开的物理文件进行关闭,目前只支持关闭单个文件。

(3)bfile数据的修改

对于bfile数据的持久引用(如存储在表中),bfile数据可以作为表的列值进行修改。

注意

  • BFILE数据类型不支持索引

  • BFILE数据类型不支持除赋值操作符以外的操作符

  • BFILE数据类型存在与字符串类型(如text)的隐士转换:

    BFILE类型数据可以转换成字符串;

    字符串在规定格式下可以成功转换成bfile,如 bfilename('directory_name','file_name')类似格式的字符串。

  • 不同文件系统类型对该类型无影响

  • 字符集影响与普通物理文件操作同理:

    读取的文件内容为二进制格式,不受字符集影响;

    文件名会作为bfile数据存入数据库,受数据库客户端和服务端字符集影响,如果客户端与服务端字符集不同可能会导致部分文件(如文件名含有中文)打开失败。

  • 执行vb_dump/vb_restore命令对数据库进行导出/导入数据时,该数据类型的数据同其他类型数据一样能被正常导出/导入。需要注意的是,directory对象的创建并不会由vb_dump/vb_restore命令进行导入/导出,因此数据导入到新库后,需手动创建 directory对象,操作系统上的物理文件也应同步手动更新到新库所在的物理机上,否则 bfile数据的使用中会报异常。

  • bfile数据类型的操作过程存在并发情况:当bfile数据已构造还未操作,另一个事务对directory对象进行修改或删除,或是删除即将读取的物理文件,会造成后续bfile数据操作失败。

示例

1、创建directory对象,创建需访问的物理文件并将其置于directory对象所指向的操作系统目录中。

create directory d_bfile as '/tmp/data/bfiletest';

2、创建包含bfile数据类型列的表(也可跳过此步骤和下一步骤,在访问 bfile数据类型时直接调用bfilename函数进行构造)。

create table testbfile(id number,bfile_name bfile);

3、将bfilename函数构造的数据插入到表中。

insert into testbfile values(1,bfilename('d_file', 'bfile.data'));

4、从表中读取数据,调用dbms_lob接口对数据进行操作,dbms_lob包的接口使用见12.20.60兼容内置包-DBMS_LOB。

select dbms_lob.getlength(bfile_name) from testbfile where id=1;
select dbms_lob.fileopen(bfilename('d_file', 'bfile.data'),0);
select dbms_lob.read(bfilename('d_bfile','bfile.data'), 1, 0, '');

set serveroutput on;
create or replace function f_read_bfile() returns void as $$
declare
buff raw;
amount int := 0 ;
offset int :=0;
lob_loc bfile;
filesize int;
begin
select bfile_name into lob_loc from testbfile1 where id=1;
--打开BFILE文件
dbms_lob.fileopen(lob_loc,0);
--获取文件大小
filesize := dbms_lob.getlength(lob_loc);
raise notice 'amount:%',amount;
--读取文件全部内容
amount = filesize;
dbms_lob.read(lob_loc,amount,0,buff);
dbms_output.put_line('file data:');
dbms_output.put_line(utl_raw.cast_to_varchar2(buff));
--读取文件前8字节内容
amount = 8;
dbms_lob.read(lob_loc,amount,offset,buff);
dbms_output.put_line('First eight bytes:');
dbms_output.put_line(utl_raw.cast_to_varchar2(buff));
--读取文件剩余内容
offset = amount;
amount = filesize - mount;
dbms_lob.read(lob_loc,amount,offset,buff);
dbms_output.put_line('The rest bytes:');
dbms_output.put_line(utl_raw.cast_to_varchar2(buff));
--关闭bfile文件
dbms_lob.fileclose(lob_loc);
return;
end;
$$ language plpgsql;

--实际的返回结果应是将文件bfile.data中的对应长度的内容打印到界面
select f_read_bfile();

--bfile数据修改示例
update bfiletest set bfile_name=bfilename('d_bfile',bfile.data') where id=1;
er) clearTimeout(resizeTimer); resizeTimer = setTimeout(function(){ refresh(); } , 500); });