Oracle 19.6 的有趣BUG:可能引发 CLOB 存储数据的丢失
时间:2022-07-22
本文章向大家介绍Oracle 19.6 的有趣BUG:可能引发 CLOB 存储数据的丢失,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
墨墨导读:世界上没有不存在 Bug 的软件,Bug 总是在变化中,层出不穷。Oracle 19c 中,一个有趣的 BUG 在国外的微博上引起热议。
首先看看如下一段代码,大家来猜测一下两次 put_line 的输出:
declare
v_clob clob :='1234567890';
v_r1 varchar2(100);
v_r2 varchar2(100);
begin
v_r1 := null || v_clob || 'ABC';
v_r2 := null || v_clob || 'ABC';
dbms_output.put_line( v_r1 || ' [' || length(v_r1) || ']');
dbms_output.put_line( v_r2 || ' [' || length(v_r1) || ']');
end;
/
你可能会说,what ? 这有什么不同?
先看看在 Oracle 11g 中的结果:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
SQL> l
1 declare
2 v_clob clob :='1234567890';
3 v_r1 varchar2(100);
4 v_r2 varchar2(100);
5 begin
6 v_r1 := null || v_clob || 'ABC';
7 v_r2 := null || v_clob || 'ABC';
8 dbms_output.put_line( v_r1 || ' [' || length(v_r1) || ']');
9 dbms_output.put_line( v_r2 || ' [' || length(v_r1) || ']');
10* end;
SQL> /
1234567890ABC [13]
1234567890ABC [13]
一切正常,可是我们再看看 Oracle 19c 中,有一点点 slightly worrying wrong 出现了,在 Patrick Jolliffe 的微博上,作者展示了这个输出:
在 Oracle 18c 、19c 中,应该都可以建到这个效果:
显然这是由于 Bug 引发的,Oracle 在处理 LOB 对象时,当对 Null 或者 empty clob 结合 String 时,遇到了这个 BUG。
Bug 号是:31142377 。问题显示在 21.1 版本中修正。但是针对 19.5 / 19.6 都有独立的补丁可以下载。
如果您的数据库中有对于 CLOB 的频繁操作,建议检查是否遇到过不曾注意到的BUG,因为这个 BUG 不会抛出异常,可能会导致数据存储的丢失。
Patch 31142377: CONCATENATION OF A NULL CLOB WITH NON-NULL DATA YIELDS WRONG RESULTS WHEN DEST. LOB IS PART OF THE CONCATENATION
官方版本的重现代码如下:
declare
datastring_bad CLOB;
datastring_good CLOB;
nullstring CLOB;
nullstring_fixed CLOB :=empty_clob();
begin
datastring_bad := 'AAAAAA';
datastring_good := 'AAAAAA';
datastring_bad := nullstring || datastring_bad || 'BBBBBB';
dbms_output.put_line('Wrong result');
dbms_output.put_line(datastring_bad);
dbms_output.put_line('Length is:'||length(datastring_bad));
datastring_good := nullstring_fixed || datastring_good || 'BBBBBB';
dbms_output.put_line('Good result');
dbms_output.put_line(datastring_good);
dbms_output.put_line('Length is:'||length(datastring_good));
end;
/
执行效果如下:
供读者参考,大家也可以看看 18c、19c 不同版本上的输出表现。
墨天轮原文链接:https://www.modb.pro/db/27833
- Linux下检测内存泄露的工具 valgrind
- 轻度Linux服务器维护人员常用的Shell脚本命令
- Gogland更名为GoLand,并附加新功能
- go(golang)中的类型转换
- 送你们几个字!对!就是MACCMS注入!
- Golang 序列化之 ProtoBuf
- 《大话数据结构》 查找 以及一个简单的哈希表例子
- 《大话数据结构》树以及赫夫曼编码的例子
- 《大话数据结构》一些基础知识
- Golang RPC 之 gRPC
- 厚土Go学习笔记 | 06. 变量
- 厚土Go学习笔记 | 05. 函数
- Implement Domain Object in Golang
- 厚土Go学习笔记 | 04. 导入和导出的不同 用math.Pi来举例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 《剑指offer》第27天:三角形最小路径和
- 《剑指offer》第26天:最大子序和
- Threat Dragon:一款针对OWASP的威胁模型构建平台
- 《剑指offer》第25天:最简单的动态规划
- 基于web页面开发串口程序界面---html代码
- Debotnet:一款针对Windows10隐私设置和数据的保护工具
- 基于web页面开发串口程序界面---代码实现
- 《剑指offer》第24天:链表相加
- 《剑指offer》第23天:删除链表倒数第N个节点
- 《剑指offer》第22天:链表成环的新解法
- 一文入门Android逆向
- 安全研究 | Slack桌面应用程序的RCE漏洞+XSS漏洞
- Softmax和Cross-entropy是什么关系?
- PyTorch多GPU并行训练方法及问题整理
- ggplot2在图上添加线性拟合方程和R值