lex*_*eme 4 database firebird firebird2.5
为了获取表模式更改的历史记录,我运行了查询:
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'
Run Code Online (Sandbox Code Playgroud)
文档说明如下:
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
Run Code Online (Sandbox Code Playgroud)
该表总共有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;
Run Code Online (Sandbox Code Playgroud)
以下是结果:
如您所见,我只有22列,无论位置还是ID都不能匹配上面日志中的24/28键.
另一个发现是在日志中有一个type=3 (VARCHAR)with sub_type=52,而37是VARCHAR的代码.
怎么了?我怎么解释这个?
我无法理解数字4,8,12,16,20,24,28背后的含义
这些是解压缩的内存缓冲区中的字节指针偏移量.
您的所有Format = 15行都具有相同的"length = 4"列.
这正是"4,8,12,16,20,24"之间的差异
在Format = 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,我建议你RDB$Formats.rdb$descriptor使用它的内置BLOB查看器查看内部值.您的日志错过了那里的一个参数,这对数字字段很重要.下面是一个表的转储.
Type=16 Scale=0 Length=8 Subtype=0 Flags=0 Offset=8
Type=17 Scale=4 Length=8 Subtype=1 Flags=0 Offset=16
Run Code Online (Sandbox Code Playgroud)
而37是VARCHAR的代码.
再次,阅读源 - ibase.h
#define blr_varying (unsigned char)37
#define blr_varying2 (unsigned char)38
Run Code Online (Sandbox Code Playgroud)
BLR代表二进制语言表示 - 它是内部Firebird的字节码,它是私有的半编译"虚拟机".我真诚地认为你真的不想深入了解低级别的实施细节.
更新:"而37是VARCHAR的代码"实际上完全记录在相应的表描述中:https:
//firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref-appx04-fields.html