oracle - 解释为什么我们需要在 nvl(dbms_lob.getlength(column_name_blob),0) OR nvl(vsize(column_name),0) 上加 1
问题描述
当我遇到http://www.dba-oracle.com/t_find_length_clob.htm时,我正在寻找在 Oracle 中查找行的长度。任何人都可以解释为什么我们需要将 1 添加到nvl(dbms_lob.getlength(column_name_blob),0)
ORnvl(vsize(column_name),0)
吗?
像:
select
nvl(dbms_lob.getlength(CASE_DATA),0)+1 +
nvl(vsize(CASE_NUMBER ),0)+1 +
nvl(vsize(CASE_DATA_NAME),0)+1 +
nvl(vsize(LASTMOD_TIME_T),0)+1
"Total bytes per row"
from
mytab
where
case = 123;
解决方案
一行存储(或多或少)为
[row header]
[length of column1] [column1 data]
[length of column2] [column2 data]
[length of column3] [column3 data]
...
其中[row header]
由 组成[flag byte][lock byte][columns count]
,即 3 个字节。
让我们看一个简单的例子——这是数据块转储中一行的转储信息:
tl: 44 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [22]
4d 61 6e 20 57 68 6f 20 53 6f 6c 64 20 54 68 65 20 57 6f 72 6c 64
col 1: [ 3] c2 14 47
col 2: [13] 42 6c 6f 6f 64 79 20 47 6f 6f 64 21 21
这里
tl
- 行的总长度 - 44 字节 - oracle 不存储它,oracle 只是为我们计算了它fb
- 标志字节lb
- 锁定字节cc
- 列长- [N] - 列数据的长度
- 以及之后的列数据
让我们手动计算这一行的长度:
- 行头:标志字节 + 锁定字节 + 列数 = 3 字节
- 第 0 列:列长(1 字节)+ 22 b = 23 字节
- 第 1 列:列长(1 字节)+ 3 b = 4 字节
- 第 2 列:列长(1 字节)+ 13 b = 14 字节
所以总 = 3 + 23 + 4 + 14 = 44 个字节,我们可以看到它等于tl
,所以我们计算正确。
当然,在迁移或链接行的情况下,您将拥有更多行标题,因此您也需要添加它们的长度。
简而言之:您可以使用这个简化的公式:3(行标题)+列数+所有列值的 vsize(),例如,对于具有 3 列(没有 LOB)的表,考虑到空值:
select
3 -- row header
+nvl(vsize(col0),1) -- even if other columns are nulls too, null will be stored as 1 byte (0xFF)
+nvl(vsize(col1), case when col2 is null then 0 else 1 end) -- 0 if there is no data after this column
+nvl(vsize(col1),0) -- oracle doesn't store trailing NULL-valued columns in row
from t
但!这与 LOB 无关: 首先,它取决于ENABLE 或 DISABLE STORAGE IN ROW选项。
LOB 列存储引用实际 LOB 值位置的定位器。本节介绍如何启用或禁用表行中的存储。
实际 LOB 值存储在表行(内联)或表行外(外联),具体取决于您在创建表时指定的列属性以及 LOB 的大小。启用 | DISABLE STORAGE IN ROW 子句用于指示 LOB 应该是内联(行内)还是外联存储。
如果设置了 ENABLE STORAGE IN ROW,则该行中存储的最大 LOB 数据量为 4000 字节。这包括控制信息和 LOB 值。
因此,如果是Inline
短 lob(<3960 字节),您可以计算它们的长度,但不能计算长 lob:首先,您需要计算 lob 定位器的长度 + lob 索引 + 计算存储数据和相乘所需的块的数量它在块大小上。并且不要忘记 LOB retention
(或pctversion
):您可能还需要计算 LOB 的旧版本
推荐阅读
- c++ - 避免使用带有虚方法的空基类的构造函数
- entity-framework - EFCore - 为什么我必须使子对象为空才能阻止它们插入?一对多
- python - 测试容器和 clickhouse 驱动程序错误:读取字节时出现意外的 EOF
- sql - SQL Schema for multiple many-to-many relationships
- javascript - Angular local reference issue in date picker
- google-cloud-platform - I have problem to connect me glassfish server from compute engine
- ios - How to send instant email with mail chimp in Swift?
- c# - 不允许请求的远程注册表访问
- javascript - Changing number in div to 2 decimal places
- mysql - How to optimize the "IN (SELECT..." query