在基于PostgreSQL wiki页面创建新表时,我已经组合了一种方法来确定您在语法data_type
中使用的内容。data_type
如果我的查询有问题,我实际上需要知道在给定场景中什么会在一个或多个查询在纯测试数据库/表上运行以修改该数据库/表的显式上下文中抛出它,所以运行这个查询以测试任何误报。
SELECT pg_attribute.attname,
format_type(pg_attribute.atttypid, pg_attribute.atttypmod),
CASE
WHEN format_type(pg_attribute.atttypid, pg_attribute.atttypmod)='bigint' THEN 'bigserial'
WHEN format_type(pg_attribute.atttypid, pg_attribute.atttypmod)='integer' THEN 'serial'
END AS type
FROM pg_index, pg_class, pg_attribute
WHERE pg_class.oid = 'delete2'::regclass
AND indrelid = pg_class.oid
AND pg_attribute.attrelid = pg_class.oid
AND pg_attribute.attnum = any(pg_index.indkey)
AND indisprimary;
这是一个带有主键的表,该表不使用此查询返回主键:
CREATE TABLE delete_key_bigserial (
test1 integer,
id bigserial NOT NULL,
col1 text,
col2 text,
test2 integer
);
您的查询将失败,因为整数的标准名称是“integer”,而不是“int”。
regtype
您可以通过比较内部OID 而不是文本表示来避免此类错误。许多基本数据类型有多个别名,它们都解析为相同的内部注册类型。除此之外,您可以在很大程度上简化和改进:
虽然这改进了查询,但它仍然没有按照您希望的那样做。
仅仅因为整数列是(部分)主键,这还不能使它成为
serial
列。以下是对 a 的详细评估serial
:您没有为所提供的表格找到任何内容,因为您的查询基于
pg_index
,这与序列类型完全无关。序列不必被索引,只有主键恰好被索引。安全解决方案
只需检测以下的串行类型
PRIMARY KEY
:如果 PK 不是串行类型,则不返回任何内容。
@jpmc26 发表 评论一个简单的检查:
只会检查列是否“拥有”序列,而不检查列默认值是否也设置为从序列中提取数字。文档:
要显示具有正确数据类型的所有列 - 在适用的情况下替换为适当的
serial
类型:对列默认值的检查可能会因
search_path
. 没有测试所有组合。db<>在这里摆弄