NULL 值导致 SELECT 结果中的空白行用于文本连接

Ran*_*all 6 postgresql null select concat

我有一个查询,用于生成一些文本以创建一些 VALUES 文本以放入 .sql 文件以插入一些行。我在结果中得到一个空行:

postgres=# SELECT '  (' || obj_id || ', ''' || obj_type || '''),' FROM il2.objects WHERE obj_id < 11 ORDER BY obj_id;
        ?column?         
-------------------------
   (1, 'ScienceDomain'),

   (3, 'PIs'),
   (10, 'Instrument'),
(4 rows)
Run Code Online (Sandbox Code Playgroud)

执行 a select *,很明显它是由obj_typeNULL 为obj_id2引起的:

postgres=# SELECT * FROM il2.objects WHERE obj_id < 11;
 obj_id |   obj_type    
--------+---------------
     10 | Instrument
      1 | ScienceDomain
      2 | 
      3 | PIs
(4 rows)
Run Code Online (Sandbox Code Playgroud)

(确认它是NULL):

postgres=# SELECT * FROM il2.objects WHERE obj_type IS NULL;
 obj_id | obj_type 
--------+----------
      2 | 
Run Code Online (Sandbox Code Playgroud)

为什么第一个SELECT给我一个空白行的结果?
即使铸造obj_type::text仍然给了我一个空白行。


附加信息:模式,它的价值:

postgres=# \d il2.objects
                                  Table "il2.objects"
  Column  |       Type        | Collation | Nullable |             Default              
----------+-------------------+-----------+----------+----------------------------------
 obj_id   | integer           |           | not null | generated by default as identity
 obj_type | character varying |           |          | 
Indexes:
    "objects_pkey" PRIMARY KEY, btree (obj_id)
Run Code Online (Sandbox Code Playgroud)

McN*_*ets 11

使用 COALESCE 函数返回当前值或空字符串。

SELECT '  (' || obj_id || ', ''' || coalesce(obj_type, '') || '''),' 
FROM   objects;
Run Code Online (Sandbox Code Playgroud)
| ?柱子?|
| :-------------- |
| (1, 'val 1'), |
| (2, ''), |
| (3, 'val 3'), |
| (4, 'val 4'), |

db<>在这里摆弄


Erw*_*ter 8

为什么第一个SELECT给我一个空白行的结果?

因为NULL与任何字符类型(或大多数其他类型,数组类型是一个显着的例外)连接会导致NULL. 有关的:

的代表NULL取决于您的客户。有些拼写出来NULL,有些(包括 psql)什么都不加。通常这是可配置的。

即使铸造obj_type::text仍然给了我一个空白行。

转换NULL为(几乎)任何类型仍然会返回NULL- 另一种数据类型。

我有一个查询,用于生成一些文本以创建一些VALUES文本以放入 .sql 文件中以插入一些行。

你有没有考虑过COPYpsql 等价物\copy

其他解决方案

如果您的示例没有简化,您可能只选择整个 ROW 值:

SELECT o  -- whole row
FROM   il2.objects o
WHERE  obj_id < 11
ORDER  BY obj_id;
Run Code Online (Sandbox Code Playgroud)

如果您需要该特定格式,请使用format()以使其简单。适用于NULL开箱即用的值:

SELECT format('(%s, %L),', obj_id, obj_type)
FROM   objects;
Run Code Online (Sandbox Code Playgroud)

你得到NULL(未加引号)代替NULL值(它不同于''并且可能必须是可区分的。)

db<> fiddle here(添加到 McNets、cudos 的现有小提琴)