sql - 具有 NULL 值的 NOT LIKE 行为

标签 sql postgresql null information-schema

我想获取一个表的所有列,串行类型的列除外。我能够提出这个问题的最接近的查询:

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 manual:

The catalog pg_attrdef stores column default values. The main information about columns is stored in pg_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/

相关文章:

mysql - MySql 中的输出参数

postgresql - 内部加入 postgresql

java - 为什么字符串输出中会出现空值?

SQL Server - 根据另一个表中的类别记录唯一更新一个表

sql - 选择 Distinct 而不排序

hibernate - 运算符不存在 : bigint = bytea

java - 哪个 Java 线程负责 PostgreSQL 数据库进程?

MySQL Sum 只有特定类别 0 否则

mysql - Concat 在 MySQL 中不起作用

sql - 按列值相同的行数排序