关于null
'anything' NOT LIKE null
的结果是null
,而不是true
。
在WHERE
子句中,只有true
符合过滤条件。
大多数函数在输入null
时返回null
(但也有例外)。这是任何正式RDBMS中null
的本质。
如果你需要一个单独的表达式,你可以使用:
AND (column_default LIKE 'nextval%') IS NOT TRUE;
然而,这并没有更短或更快。详情请参阅手册。
正确的查询
您的查询仍然不可靠。在Postgres数据库中,仅表名不足以唯一确定一个表,您需要添加模式名称或依赖于当前search_path
来查找第一个匹配项:
相关信息:
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'hstore1'
AND table_schema = 'public'
AND (column_default IS NULL
OR column_default NOT LIKE 'nextval%');
更好了,但仍不是百分之百安全的。以“nextval”开头的列默认值还不算是一个
serial
。请参见:
Auto increment table column。若要确认,请检查所使用的序列是否被
pg_get_serial_sequence(table_name, column_name)
“拥有”。
我很少使用信息模式。那些缓慢、臃肿的视图确保在主要版本之间具有可移植性,并且旨在实现对其他符合标准的关系型数据库管理系统的可移植性。但是,许多内容仍然不兼容。Oracle 甚至在 2015 年时都没有实现信息模式。
此外,信息模式中缺少一些有用的 Postgres 特定列。对于这种情况,我可能会像这样查询系统目录:
SELECT *
FROM pg_catalog.pg_attribute a
WHERE attrelid = 'table1'::regclass
AND NOT attisdropped
AND attnum > 0
AND NOT EXISTS (
SELECT FROM pg_catalog.pg_attrdef d
WHERE (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
AND d.adsrc LIKE 'nextval%'
AND pg_get_serial_sequence(a.attrelid::regclass::text, a.attname) <> ''
);
更快、更可靠,但不太便携。
手册:
目录项 pg_attrdef
存储列的默认值。有关列的主要信息存储在 pg_attribute
中(请参见下文)。只有明确指定了默认值(在创建表或添加列时)的列才会在此处有条目。
'table1'::regclass
使用 search_path
解析名称以避免歧义。您可以使用模式限定符覆盖:'myschema.table1'::regclass
。
相关内容:
IS NULL
或IS NOT NULL
会返回NULL
而不是true或false。 - Sam DeHaan