PLS_INTEGER
PLS_INTEGER数据类型保存范围-2147483648到2147483647的有符整数。这种类型的值是通过底层硬件平台的原生整数格式来表示的。
设计PLS_INTEGER数据类型是为了运算速度。在oracle数据库10g以前,PLS_INTEGER是唯一的一个使用原生机器算法的整数类型。其他的所有数值烈性的数据类型都和NUMBER数据类型一样使用C语言算法库。如果用PLS_INTEGER值运算,oracle软件会使用原生机器算法。结果就是处理PLS_INTEGER值的速度要比处理NUMBER类型的整数快的多。因为PLS_INTEGER是整数,因此在一直硬件平台时不会遇到兼容性的问题、
如果要处理的是密集整数运算,建议使用PLS_INTEGER、不过要记住,如果使用PLS_INTEGER时要经常和NUMBER类型互相转换,那还是从一开始就使用NUMBER类型更好。
如果这个数据类型用于整数运算,结果会取整
declare
pls1 PLS_INTEGER;
pls2 PLS_INTEGER;
p_result PLS_INTEGER;
num number;
begin
pls1 := 100;
pls2 := 49;
p_result := pls2/pls1;
num := pls2/pls1;
dbms_output.put_line('integer 49/100='||p_result);
dbms_output.put_line('number 49/100='||num);
pls2 := 50;
p_result := pls2/pls1;
num := pls2/pls1;
dbms_output.put_line('integer 50/100='||p_result);
dbms_output.put_line('number 50/100='||num);
end;
/
integer 49/100=0
number 49/100=.49
integer 50/100=1
number 50/100=.5
PL/SQL 过程已成功完成。
BINARY_INTEGER
BINARY_INTEGER数据类型也可以用二进制的形式保存有符号整数。这个类型的语义在oracle数据库10g的R1版本中有所不同。从这个版本开始,BINARY_INTEGER等同于PLS_INTEGER。而在oracle数据库9i的R2版本以及更早的版本中,它和PLS_INTEGER的区别在于oracle采用平台无关的库代码来实现。
我不建议在新代码中使用BINARY_INTEGER类型。使用BINARY_INTEGER的唯一理由就是你的代码要在oracle 7.3以前版本上运行(即PLS_INTEGER引入之前)。我希望你不会还在使用这么旧的版本
SIMPLE_INTEGER类型
SIMPLE_INTEGER数据类型时在oracle数据库11g中新出现的。这个数据类型是PLS_INTEGER的性能增强版本,除了很少几个警告。SIMPLE_INTEGER和PLS_INTEGER有相同的取值范围,但是它不支持NULL值,也不会检查溢出条件。所以你可能很奇怪为何需要使用这个看起来有缺陷的PLS_INTEGER。很好,如果你的变量永远不会为NULL,也不会溢出,而且用原生的方式编译你的代码,SIMPLE_INTEGER类型能带来令人尖叫的性能。
首先,创建一个使用pls_integer的计算密集型的过程
create or replace procedure pls_test(interations in pls_integer)
as
int1 pls_integer := 1;
int2 pls_integer := 2;
begints timestamp;
endts timestamp;
begin
begints := systimestamp;
for cnt in 1..interations loop
int1 := int1 + int2 * cnt;
end loop;
endts := systimestamp;
dbms_output.put_line( interations
|| 'interations had run time of:'
|| to_char(endts - begints));
end;
/
接下来用simple_integer创建相同的过程
create or replace procedure simple_test(interations in simple_integer)
as
int1 simple_integer := 1;
int2 simple_integer := 2;
begints timestamp;
endts timestamp;
begin
begints := systimestamp;
for cnt in 1..interations loop
int1 := int1 + int2 * cnt;
end loop;
endts := systimestamp;
dbms_output.put_line( interations
|| 'interations had run time of:'
|| to_char(endts - begints));
end;
/
首先以解释的方式重新编译代码
alter procedure pls_test compile plsql_code_type=interpreted;
/
alter procedure simple_test compile plsql_code_type=interpreted;
/
exec pls_test(12345);
exec simple_test(12345);
alter procedure pls_test compile plsql_code_type=native;
/
alter procedure simple_test compile plsql_code_type=native;
/
我做的实验simple_integer更慢了。。
书上的实验:
在使用解释代码时,simple_integer只有少许系能提升(windows)。在使用原生编译时,PLS_INTEGER和SIMPLE_INTEGER两个都更快,但是原生simple_integer要比原生PLS_INTEGER快300%!作为一个教学用的练习,用NUMBER再做一下这个实验——我发现SIMPLE_INTEGER要比NUMBER块1000%。在运行与Linux服务器上的Oracle数据库11g的R2版本中,使用SIMPLE_INTEGER类型后同样得到显著的性能提升(快上百分之几百)。