我想获取除serial类型列之外的表的所有列。最接近这个问题的查询我能够想出这个问题:
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%')
欢迎提出任何更好的建议或理由。
答案 0 :(得分:15)
NULL
'anything' NOT LIKE NULL
会产生NULL
,而非TRUE
只有TRUE
符合WHERE
子句中的过滤表达式。
大多数函数在NULL
输入上返回NULL
(有例外)。这是任何适当的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)
的列中。
我很少自己使用信息模式。这些缓慢,臃肿的视图保证了主要版本的可移植性 - 并且旨在实现其他符合标准的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) <> ''
);
更快,更可靠,但便携性更低。
目录
pg_attrdef
存储列默认值。主要的 有关列的信息存储在pg_attribute
中(见下文)。只要 显式指定默认值的列(表格为时) 已创建或添加了列)将在此处输入一个条目。
'table1'::regclass
使用search_path
来解析名称,从而避免歧义。您可以对名称进行架构限定以取代:'myschema.table1'::regclass
。
相关:
答案 1 :(得分:-1)
.encode("utf-8")
也可以写
AND column_default NOT LIKE 'nextval%' OR column_default IS NULL
答案 2 :(得分:-2)
我认为你可以使用:
SELECT column_name *FROM* information_schema.columns
WHERE table_name = 'table1'
AND ( nvl(column_default,0) *NOT LIKE* 'nextval%');