plsql binary_integer、pls_integer、simple_integer 区别详解

1 概述

1. 结论:三者都是 '整数类型',但使用场景不用

2. 使用优先级: simple_integer > pls_integer > binary_integer
   (1) 如果没有 '数据溢出',也不支持 null,优先使用 simple_integer
   (2) 如果没有 '数据溢出',支持 null,推荐使用 pls_integer
   (3) 若上述均不满足,则使用 binary_integer
整数类型解释相同点不同点
binary_integeroracle 9.2 之前,Oracle 底层运算,效率一般1. 整数类型,四舍五入

2. 数据精度: [-2^31, 2^31), 半闭半开区间
1. 默认值:binary_integer 和 pls_integer 都是 null,simple_integer 是 not null

2.执行速度:Simple_integer > Pls_Integer > Binary_Integer

3.运算溢出:Binary_Integer、Pls_Integer 会,Simple_integer 不会
pls_integer oracle 9.2 之后,11g 之前常用,CPU 运算,效率较快
simple_integeroracle 11g 之后出现,效率最快,但不能为 null
number既有整数类型,又有小数类型number(p, s)
p:1 -- 38
s:-84 -- 127
隐式数据类型转换
上述三种类型中,只有 simple_integer + number = number

2 相同点

2.1 整数类型,四舍五入

declare
  b1 binary_integer; -- binary_integer 和 pls_integer 默认 null
  b2 binary_integer;
  p1 pls_integer;
  p2 pls_integer;
  s1 simple_integer := 1.2; -- simple_integer not null,故变量必须初始化
  s2 simple_integer := 1.5;
begin
  b1 := 1.2;
  b2 := 1.5;
  p1 := 1.2;
  p2 := 1.5;

  -- 验证: 小数运算时, "四舍五入"
  dbms_output.put_line('b1: ' || b1 || ', b2: ' || b2);
  dbms_output.put_line('p1: ' || b1 || ', p2: ' || b2);
  dbms_output.put_line('s1: ' || b1 || ', s2: ' || b2);
end;

输出结果:小数部分 被 四舍五入

b1: 1, b2: 2
p1: 1, p2: 2
s1: 1, s2: 2

2.2 数据精度一致

declare
  init_min number := power(-2, 31);
  init_max number := power(2, 31);
  b_min    binary_integer;
  b_max    binary_integer;
  p_min    pls_integer;
  p_max    pls_integer;
  s_min    simple_integer := 0; -- 必须初始化
  s_max    simple_integer := 0;
begin
  -- 验证: 数据精度
  dbms_output.put_line('power(-2, 31): ' || init_min || 
                       ', power(2, 31): ' || init_max);

  -- p_min、s_min 同理
  -- b_min := init_min - 1; -- 超出数据精度,报错
  -- b_max := init_max;     -- 超出数据精度,报错

  b_min := init_min;
  b_max := init_max - 1;
  
  dbms_output.put_line('b_min: ' || b_min || ', b_max: ' || b_max);
end;

输出结果:

power(-2, 31): -2147483648, power(2, 31): 2147483648
b_min: -2147483648, b_max: 2147483647

3 不同点

3.1 执行效率

-- 基础数据准备
create table stu_info (
   id   number(10),
   name varchar2(30)
);

-- 数据表
create table stu_info_simple as select * from stu_info where 1 = 2;
create table stu_info_pls as select * from stu_info where 1 = 2;
create table stu_info_binary as select * from stu_info where 1 = 2;

结论:执行效率 Simple_integer > Pls_Integer > Binary_Integer

declare
   v_binary_integer binary_integer := 10000; -- 测试 1w 条记录
   v_pls_integer    pls_integer := 10000;
   v_simple_integer simple_integer := 10000;
   v_start_date     simple_integer := 0; -- 100 = 1s
   v_end_date       simple_integer := 0; 
   -- 100 = 1s 的验证思路如下:
   -- https://blog.csdn.net/qq_34745941/article/details/105984524
begin
   -- binary_integer 验证
   v_start_date := dbms_utility.get_time;
   for i in 1 .. v_binary_integer loop
      insert into stu_info_binary (id, name) values (1, 'a' || i);
   end loop;
   commit;
   v_end_date := dbms_utility.get_time;
   dbms_output.put_line('binary_integer 用时: ' ||
                        (v_end_date - v_start_date) / 100 || ' 秒');

   -- pls_integer 验证
   v_start_date := dbms_utility.get_time;
   for i in 1 .. v_pls_integer loop
      insert into stu_info_pls (id, name) values (1, 'a' || i);
   end loop;
   commit;
   v_end_date := dbms_utility.get_time;
   dbms_output.put_line('pls_integer    用时: ' ||
                        (v_end_date - v_start_date) / 100 || ' 秒');

   -- simple_integer 验证
   v_start_date := dbms_utility.get_time;
   for i in 1 .. v_simple_integer loop
      insert into stu_info_simple (id, name) values (1, 'a' || i);
   end loop;
   commit;
   v_end_date := dbms_utility.get_time;
   dbms_output.put_line('simple_integer 用时: ' ||
                        (v_end_date - v_start_date) / 100 || ' 秒');
end;

输出结果:(数据量越大、差距越明显)

binary_integer 用时: .62 秒
pls_integer    用时: .59 秒
simple_integer 用时: .6

3.2 运算时,精度溢出,存疑

网上说,Simple_integer 、Pls_Integer 运算会溢出 而 Binary_Integer 不会
因为:binary_integer 运算溢出时,会自动指派给一个 number 类型,从而避免报错
这点暂不知道如何证明,后续若知晓如何用实例证明,咱再修改

  • binary_integer、pls_integer 会报超出精度的错误,simple_integer 不会
  • 故与网上 运算溢出 的描述有误,暂存疑,验证思路如下:
declare
   init_min number := power(-2, 31);
   init_max number := power(2, 31);
   -- b_min    binary_integer;
   b_max binary_integer;
   -- p_min    pls_integer;
   p_max pls_integer;
   -- s_min    simple_integer := 0; -- 必须初始化
   s_max simple_integer := 0; -- 必须初始化
   n     number;
begin
   -- 验证: 数据精度
   dbms_output.put_line('power(-2, 31): ' || init_min ||
                        ', power(2, 31): ' || init_max);

   -- 不会报错,但数据精度异常,存在 数据隐式转换 s_max + number = number
   -- b_max、p_max 则直接报错:ORA-01426: 数字溢出
   s_max := init_max - 1;
   n := s_max + 1;
   
   dbms_output.put_line('最大值:' || n);
end;

输出结果:

power(-2, 31): -2147483648, power(2, 31): 2147483648
最大值:-2147483648
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼丸丶粗面

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值