plsql programming 13 其他数据类型
bolean 类型
raw 类型, 用来保存和操作少量的二进制数据.
urowid 和 rowid 类型, 这两种数据类型表示数据库的 rowid. 所谓 rowid 就是一个标识符-用来表示数据库中一行记录的物理地址的二进制值. 一个rowid值可以唯一的标识出数据库表中的一行数据, 即便这个表没有唯一键. 两行记录就算是所有列的值都完全相同, 但是会有不同的 rowid 或者 urowid.
从历史上说, rowid 类型要比 urowid 出现的早, 伴随着 Oracle 增加的新功能, 比如 索引组织表(IOT), 与其他类型数据库实现联通的网关, oracle 也退出了新的 rowid 类型, 因此也必须开发一个新的数据类型能够容纳这些rowid, 这就是 urowid数据类型, u代表通用的, 一个 urowid 变量可以用于任何类型表的任何rowid.
建议: 在所有新开发中都使用 urowid.
获得 rowid
1: declare
2: employee_rowid urowid;
3: employee_salary number;
4: begin
5: select rowid, salary into employee_rowid, employee_salary
6: from employees
7: where last_name = 'Raphaely' AND first_name = 'Den';
8: dbms_ouput.put_line('salary is : ' || employee_salary);
9: exception
10: when no_data_found then
11: dbms_output.put_line('There is no data what you want');
12: end;
13: /
使用 rowid
rowid 主要用于对一行数据的反复访问, 使用 rowid 作为查询条件, 可以跳过索引查找, 直接定位行, 速度奇快.
1: declare
2: employee_rowid urowid;
3: employee_salary number;
4: begin
5: select rowid, salary into employee_rowid, employee_salary
6: from employees
7: where last_name = 'Raphaely' AND first_name = 'Den';
8:
9: update employees
10: set salary = employee_salary
11: where rowid = employee_rowid;
12:
13: dbms_output.put_line('salary modified: ' || employee_salary);
14: exception
15: when no_data_found then
16: dbms_output.put_line('There is no data what you want');
17: end;
18: /
危险, plsql 执行中, 如果多用户系统下, 某个用户对表进行了变更, 例如 dba 对表进行了联机重组, 那么这个rowid的值就会发生变化, 上面的plsql 执行的结果就是错误的, 所以更好的办法是使用显示游标提取数据, 然后使用 where current of cursor 语句来修改或者删除数据.
LOB 数据类型
可以声明为 LOB 变量 如下:
BFILE: 二进制文件. 这种变量的内容是一个指向数据库外部的操作系统文件的指针. 数据库把文件的数据按照二进制数据处理.
BLOB: 二进制大对象. 这种变量的内容也是一个指向保存在数据库内部的大二进制对象的指针.
CLOB: 字符型大对象. 这种变量保存的内容是一个指向保存在数据库内部的巨大的字符对象. 字符使用数据库字符集.
NCLOB: 国家字符集大对象, 同上, 只不过字符集使用的是国家字符集.
外部LOB(BFILE) 不参与到事务中, 换句话说, 我们不能把对 BFILE 的修改进行提交或者回滚.
使用 LOB
1: -- create table
2: create table waterfalls (
3: falls_name varchar2(80),
4: falls_photo BLOB,
5: falls_directions CLOB,
6: falls_description NCLOB,
7: falls_web_page BFILE
8: );
照片本身就是一个二进制文件, 所以定义为 BLOB 类型
理解 LOB 定位符( 指针 )
LOB 定位符是指向数据库中的大对象数据的指针.
1: declare
2: photo blob;
3: begin
4: select falls_photo
5: into photo
6: from waterfalls
7: where falls_name = 'Dryer Hose';
这个 select 语句执行完毕, 这个 photo 变量到底是什么呢? 图片本身? 不, 只是一个指向要访问图片的指针.

注意, 大对象本身是保存在数据库内 BLOB 类型存储在数据库内, 但是 photo 变量本身只是一个指针.
要使用 LOB 数据, 我们必须先取出 LOB 定位符( 指针 ), 然后再通过内置的 DBMS_LOB 包来提取或者修改真正的 LOB 数据。流程可参考如下, 例子:
1. 用 select 语句取出要显示的图片的 LOB 定位符
2. 调用 DBMS_LOB.OPEN 打开LOB对象
3. 调用 DBMS_LOB.GETCHUNKSIZE 得到读写 LOB 值应该设置的最优的块大小
4. 调用 DBMS_LOG.GETLENGTH 得到 LOB 值得字节或者字符数量
5. 多次调用 DBMS_LOG.READ 取得 LOB 数据
6. 关闭 LOB
LOB 数据缺省不会在 Buffer Cache 中缓存, 也不会像普通数据一样产生 undo 信息, 不过 LOB 会像普通数据一样生成 redo 信息, 除非我们使用 NOLOGGING 选项.
LOB 变量, 我们在使用的时候要检查两项, 一个是 null , 另一个是 长度是 0 , 例如
vlob CLOB; -- 你定义了一个 clob 变量, 这时 vlob 是 null 的
vlob := EMPTY_CLOB(); 这时的 vlob 已经不等于 null, 但是同样它也不可直接使用. 所以要判断两次, 如下:
1: IF some_clob IS NULL THEN
2: -- 没有数据
3: ELSIF DBMS_LOB.GETLENGTH(some_lob) = 0 THEN
4: -- 没有数据
5: ELSE
6: -- 只有这样才有数据, 可以正常使用
7: END IF;
向 LOB 中写入数据
DBMS_LOB.WRITE : 向 LOB 中随机写入数据.
DBMS_LOB.WRITEAPPEND : 向 LOB 的末尾追加数据.
1: declare
2: directions CLOB;
3: amount BINARY_INTEGER;
4: offset INTEGER;
5: first_direction VARCHAR2(100);
6: more_directions VARCHAR2(500);
7: begin
8: -- 先删除, 这样这个例子可以重复执行
9: delete
10: from waterfalls
11: where falls_name = 'Munising Falls';
12:
13: -- 插入新的一行, 用 EMPTY_CLOB()创建一个LOB定位符
14: insert into waterfalls(falls_name, falls_directions)
15: values('Munising Falls', EMPTY_CLOB());
16:
17: -- 取出刚才这个 insert 语句创建的定位符
18: select falls_directions
19: into directions
20: from waterfalls
21: where falls_name = 'Munising Falls';
22:
23: -- 打开 LOB; 严格来说不是必须这么做, 不过最好这么做
24: DBMS_LOB.OPEN(directions, DBMS_LOB.LOB_READWRITE);
25:
26: -- 开始 DBMS_LOB.WRITE
27: first_direction := 'Follow I-75 across the Mackinac Birdge.';
28: amount := LENGTH(first_direction);
29: offset := 1;
30: DBMS_LOB.WRITE(directions, amount, offset, first_direction);
31: more_directions := 'asdfjdsajflkdasjklfdlkjsfkldas' ||
32: 'fdajsfkldjasfldjlksafjkldsaljkfjldk' ||
33: 'fdajsklfjdlajkfldjasklfjklda';
34: DBMS_LOB.WRITEAPPEND(directions, LENGTH(more_directions), more_directions);
35:
36: -- 关闭 LOB, 结束工作
37: DBMS_LOB.CLOSE(directions);
38: END;
读取 LOB 数据
读取数据, 与上面基本相同, 要使用 DBMS_LOB.READ 函数, 另外就是不需要 DBMS_LOB.OPEN 这个函数了.
1: declare
2: directions CLOB;
3: directions_1 varchar2(300);
4: directions_2 varchar2(300);
5: chars_read_1 binary_integer;
6: chars_read_2 binary_integer;
7: offset integer;
8: begin
9:
10: -- 取出刚才这个 insert 语句创建的定位符
11: select falls_directions
12: into directions
13: from waterfalls
14: where falls_name = 'Munising Falls';
15:
16: offset := 1;
17: chars_read_1 := 10;
18: DBMS_LOB.READ(directions, chars_read_1, offset, directions_1);
19: IF chars_read_1 = 10 then
20: offset := offset + char_read_1;
21: chars_read_2 := 50;
22: dbms_lob.read(directions, chars_read_2, offset, directions_2);
23: else
24: chars_read_2 := 0;
25: directions_2 := '';
26: end if;
27:
28: dbms_output.put_line('Characters read = ' || to_char(chars_read_1 + chars_read_2));
29: dbms_output.put_line(directions_1);
30: dbms_output.put_line(directions_2);
31: END;
32: /
BFILE 有所不同, 因为它的实际文件存储在操作系统上, 一般而言, 在 PL/SQL 和 oracle 数据库内部, 我们对BFILE只能读取. 但是我们要读取 BFILE, 我们同样需要定位符指针, 这个指针由一个目录别名和文件名组成.
create directory bfile_data as ‘c:\plsql book\Ch13\’ 这个就是一个目录别名.
grant read on directory bfile_data to hr;
一个BFILE定位符只不过是目录别名和文件名的组合.
创建一个 bfile 定位符
1: declare
2: web_page bfile;
3: begin
4: -- 调用 bfilename 函数创建 bfile定位符
5: web_page := bfilename('bfile_data', 'document.htm');
一旦我们拥有了定位符, 我们就可以用和 BLOB 一样的方式访问外部文件.
另外还有一些, xml 类型, any 类型, url 类型, 感觉不常用, 忽略了.
plsql programming 13 其他数据类型的更多相关文章
- PLSQL Developer 13.0.0.1883 注册码
PLSQL Developer 13.0.0.1883 注册码 product code: 4vkjwhfeh3ufnqnmpr9brvcuyujrx3n3le serial Number:22695 ...
- 《从零开始学Swift》学习笔记(Day 13)——数据类型之整型和浮点型
Swift 2.0学习笔记(Day 13)——数据类型之整型和浮点型 原创文章,欢迎转载.转载请注明:关东升的博客 Swift提供8.16.32.64位形式的有符号及无符号整数.这些整数类型遵循 ...
- PLSQL Developer 13安装教程
1:双击安装包进行安装.点击"next".2:点击"w accept the termis..."同意条款,并点击"next",进行下一步. ...
- plsql programming 16 动态SQL和动态PLSQL
动态SQL 是指在执行时才构建 SQL 语句, 相对于静态 sql 的编译时就已经构建. 动态PLSQL 是指整个PL/SQL代码块都是动态构建, 然后再编译执行的. 作用: 1. 可以支持 DDL ...
- plsql programming 14 DML和事务管理
我们可以把多个SQL语句集中在一起, 在逻辑上组成一个事务, 从而保证这些操作或者全部被保存到数据库(用sql的说法就是”提交”), 或者被整体驳回(用sql的说法是“回滚”). 事务: ACID 原 ...
- plsql programming 11 记录类型
记录类型非常类似数据库表中的行. 记录作为一个整体本身并没有值, 不过每个单独成员或字段都有值, 记录提供了一种把这些值当做一组进行操作的方法. 例如: 1: -- create a table 2: ...
- plsql programming 09 数字
number 类型, 十进制数据类型(平台无关的) pls_integer 和 binary_integer 这两种数据类型和你底层硬件表示整数的方法完全一致, 这两种类型的运算是利用硬件原生, 机器 ...
- plsql programming 10 日期和时间戳
年 月 日 时 分 秒 时区 用小时表示的相对于 UTC 的时差 用分钟表示的相对于 UTC 的时差 date 存储日期和时间, 不带时区, 精确到秒 timestamp 存储日期和时间, 不带时区, ...
- plsql programming 07 使用数据
数据类型 char, Nchar varchar2, Nvarchar2 clob, Nclob number number(9, 2); -- 定点小数, 小数点左边7位, 右边2位 number ...
随机推荐
- 国内流行的开源.net微信公众平台SDK对比分析
一.引言 目前微信公众平台正如火如荼的进行中,微信虽然在海外市场不敌WhatsApp,但是已经俘获了国内绝大部分用户的心.作为国内最大的,超级"app",微信已算是成功问鼎了.公众 ...
- NHibernate官方文档中文版——持久化类(Persistent Classes)
持久化类是一个应用程序中的类,主要用来实现业务逻辑(例如,在电商应用中的客户和订单类).持久化类,就像它的名字一样,生命周期短暂并且用来持久化的据库对象实例. 如果这些类的构造能够依照一些简单的原则, ...
- 【教训】 form表单提交时,action url中参数无效
今天提交一个表单,内容参考如下: <form action="add.php?a=123&b=456"> <input type="hi ...
- SQL:将查询结果插入到另一个表的三种情况!
一:如果要插入目标表不存在: select * into 目标表 from 表 where ... 二:如果要插入目标表已经存在: insert into 目的表 select * from 表 wh ...
- oracle 百万行数据优化查询
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使 ...
- OpenGL ES2.0编程三步曲 -转
原地址:http://blog.csdn.net/myarrow/article/details/7707943 1. 保存全局变量的数据结构 以下例子程序均基于Linux平台. typedef st ...
- React脚手架
所谓脚手架,是指一套基础的开发环境,你只需要简单的配置或者无需配置,就可以直接开发自己的业务代码,而无需劳神在搭建环境上. 比较出名的就是facebook自己出的的脚手架:create-react-a ...
- Discuz! 6.x/7.x 全局变量防御绕过漏洞
受影响产品: Discuz! 6.x/7.x 漏洞描述: 由于php5.3.x版本里php.ini的设置里request_order默认值为GP,导致Discuz! 6.x/7.x 全局变量防御绕过漏 ...
- 创建 git仓库
首先创建一个文件夹作为git仓库,创建一个test文件夹,并在文件夹下创建一个test.c的文件用以测试: git init git使用git init来初始化一个git仓库,git的很多命令都是在g ...
- 理解JS中的模块规范(CommonJS,AMD,CMD)
随着互联网的飞速发展,前端开发越来越复杂.本文将从实际项目中遇到的问题出发,讲述模块化能解决哪些问题,以及如何使用 Sea.js 进行前端的模块化开发. 恼人的命名冲突 我们从一个简单的习惯出发.我做 ...