我正在尝试运行一个查询来提取Firebird中所有列的元数据。以下是它的样子:
select
f.RDB$RELATION_NAME as tableName,
f.RDB$FIELD_NAME name,
fd.RDB$FIELD_TYPE type,
fd.RDB$FIELD_SCALE scale,
fd.RDB$FIELD_SUB_TYPE subtype,
fd.RDB$DIMENSIONS dimensions,
fd.RDB$NULL_FLAG notNull,
fd.RDB$FIELD_PRECISION precision
from rdb$relation_fields f
join rdb$relations r on f.RDB$RELATION_NAME = r. RDB$RELATION_NAME
join RDB$FIELDS fd on fd.RDB$FIELD_NAME = f.RDB$FIELD_SOURCE
where f.RDB$UPDATE_FLAG = 1
and r.RDB$RELATION_TYPE = 0
and coalesce(r.RDB$SYSTEM_FLAG, 0) = 0
在大多数情况下,它运行良好。但无论出于何种原因,每个结果都会在fd.RDB$NULL_FLAG
列中给出null
。根据文档,如果列可以为null,则该值应为null
,如果不可以为null则为1
。(不用说,事实上,我的数据库中确实有一些NOT NULL
列!(
知道哪里出了问题吗?我如何才能正确地报告列的可空性状态?
要扩展user13964273的答案,表的字段定义为两部分:RDB$RELATION_FIELDS
中字段本身的条目和RDB$FIELDS
中的域定义。如果用基本类型而不是(命名的(域定义字段,则会生成未命名(编号的(域。
这个未命名的域没有设置RDB$NULL_FLAG
,这相当于CREATE DOMAIN <domainname> <basicdatatype>
,它也没有在RDB$FIELDS
中设置RDB$NULL_FLAG
。相反,NOT NULL
约束被记录在RDB$RELATION_FIELDS.RDB$NULL_FLAG
中。
当创建具有NOT NULL
约束的显式域时,RDB$FIELDS.RDB$NULL_FLAG
仅填充1
,例如:
create domain int_not_null integer not null;
简而言之,您需要使用(例如(COALESCE(f.RDB$NULL_FLAG, fd.RDB$NULL_FLAG, 0)
来确定列的可为Null性,其中0
表示可为Null,1
表示不可为Null。
对两个表中的值进行类似的检查也适用于RDB$FIELDS
和RDB$RELATION_FIELDS
中存在的其他几列:RDB$DEFAULT_VALUE
/RDB$DEFAULT_SOURCE
和RDB$COLLATION_ID
。
您还应该检查覆盖域定义的f.RDB$NULL_FLAG。