我想获取一个表的所有列,串行类型的列除外。我能够提出这个问题的最接近的查询:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1' AND column_default NOT LIKE 'nextval%'
但问题是它还排除/过滤了 column_default 具有空值的行。我不知道为什么 Postgres 的行为是这样的。所以我不得不将查询更改为如下内容:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1'
AND ( column_default IS NULL OR column_default NOT LIKE 'nextval%')
欢迎提出任何更好的建议或理由。
最佳答案
关于null
'anything' NOT LIKE null
产生 null
,而不是 true
。
并且只有 true
符合 WHERE
子句中的过滤器表达式。
大多数函数在 null
输入时返回 null
(也有异常(exception))。这就是任何适当的 RDBMS 中 null
的性质。
如果你想要一个单个表达式,你可以使用:
AND (column_default LIKE 'nextval%') IS NOT TRUE;
不过,这并没有更短或更快。 Details in the manual.
正确查询
您的查询仍然不可靠。单独的表名在 Postgres 数据库中不是唯一的,您需要另外指定模式名称或依赖当前的 search_path
来找到其中的第一个匹配项:
相关:
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'hstore1'
AND table_schema = 'public' -- your schema!
AND (column_default IS NULL
OR column_default NOT LIKE 'nextval%');
更好,但仍然不是防弹的。以“nextval”开头的列默认值不会生成 serial
。见:
可以肯定的是,检查正在使用的序列是否由带有 pg_get_serial_sequence(table_name, column_name)
的列“拥有” .
我自己很少使用信息架构。那些缓慢、臃肿的 View 保证了跨主要版本的可移植性——并旨在可移植到其他符合标准的 RDBMS。但无论如何,太多是不相容的。 Oracle 甚至没有实现信息模式(截至 2015 年)。
此外,信息模式中缺少有用的特定于 Postgres 的列。对于这种情况,我可能会像这样查询系统目录:
SELECT *
FROM pg_catalog.pg_attribute a
WHERE attrelid = 'table1'::regclass
AND NOT attisdropped -- no dropped (dead) columns
AND attnum > 0 -- no system columns
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) <> ''
);
更快、更可靠,但便携性较差。
The catalog
pg_attrdef
stores column default values. The main information about columns is stored inpg_attribute
(see below). Only columns that explicitly specify a default value (when the table is created or the column is added) will have an entry here.
'table1'::regclass
使用 search_path
解析名称,避免歧义。您可以对要否决的名称进行架构限定:'myschema.table1'::regclass
。
相关:
关于sql - 具有 NULL 值的 NOT LIKE 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22818070/