要获取表架构更改的历史记录,我运行了查询:
select CAST(SUBSTRING(f.rdb$descriptor FROM 1 FOR 32000) AS VARCHAR(32000)) log
from rdb$formats f
join rdb$relations r on r.rdb$relation_id = f.rdb$relation_id
where r.rdb$relation_name = 'MY_TABLE_NAME'
godbolt demo声明如下:
RDB $ DESCRIPTOR | BLOB格式|将列名称和数据属性存储为BLOB,就像创建格式记录时一样
以下是查询结果:
LOG TABLE FORMAT ID
------------------------------------------------- ----------------
4: type=9 (LONG) length=4 sub_type=0 flags=0x0 15
8: type=9 (LONG) length=4 sub_type=0 flags=0x0
12: type=14 (DATE) length=4 sub_type=0 flags=0x0
16: type=9 (LONG) length=4 sub_type=0 flags=0x0
20: type=9 (LONG) length=4 sub_type=0 flags=0x0
24 <-- probably truncated?
------------------------------------------------- ----------------
4: type=9 (LONG) length=4 sub_type=0 flags=0x0 16
8: type=3 (VARCHAR) length=12 sub_type=52 flags=0x0
20: type=14 (DATE) length=4 sub_type=0 flags=0x0
24: type=9 (LONG) length=4 sub_type=0 flags=0x0
28: type=9 (LONG) length=4 sub_type=0 flags=0x0
该表共有28行事件。但我无法理解数字4,8,12,16,20,24,28背后的含义。好的,让我们发出以下查询:
SELECT
RF.RDB$FIELD_POSITION,
RF.RDB$FIELD_ID,
F.RDB$FIELD_TYPE,
F.RDB$FIELD_SUB_TYPE
FROM RDB$RELATION_FIELDS RF
JOIN RDB$FIELDS F ON (F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE)
WHERE RF.RDB$RELATION_NAME = 'MY_TABLE_NAME'
ORDER BY RF.RDB$FIELD_POSITION;
以下是结果:
如您所见,我只有22列,位置和 ID 都不能匹配上述日志中的24/28键。
另一个发现是日志中有type=3 (VARCHAR)
sub_type=52
,而37是VARCHAR的代码。
发生了什么事?我怎么解释这个?
答案 0 :(得分:6)
我无法理解数字4,8,12,16,20,24,28背后的含义
这些是解压缩的内存缓冲区中的字节指针偏移量。
你所有的格式= 15行都有相同的&#34;长度= 4&#34;列。
而这正是&#34; 4,8,12,16,20,24和#34之间的差异;
在格式= 16行中,长度为4,12,4,4,4 这些是匹配偏移之间的差距:4,8,20,24,28
如果您需要进入低级别,请阅读低级文档:
c:\Program Files\Firebird\Firebird_2_1\include\ibase.h
- dtype_XXX及相关常量
select CAST(SUBSTRING....
由于您提到了 IBExpert ,我建议您使用内置的BLOB查看器查看RDB$Formats.rdb$descriptor
值。您的日志错过了那里的一个参数,这对数字字段很重要。下面是一个表格中的转储。
Type=16 Scale=0 Length=8 Subtype=0 Flags=0 Offset=8
Type=17 Scale=4 Length=8 Subtype=1 Flags=0 Offset=16
而37是VARCHAR的代码。
再次阅读来源 - ibase.h
#define blr_varying (unsigned char)37
#define blr_varying2 (unsigned char)38
BLR代表二进制语言表示 - 它是内部Firebird的字节码,它是私有的半编译虚拟机&#34;。我真诚地认为你真的不想深入了解低级别的实施细节。
更新:&#34;而37是VARCHAR的代码&#34;实际上是完全记录在相应的表格描述中:
https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref-appx04-fields.html