web-dev-qa-db-ja.com

NULL値により、テキスト連結のSELECT結果に空白行が発生する

行を挿入するために.sqlファイルに入れるVALUESテキストを作成するためのテキストを生成するクエリがあります。結果に空白行が表示されます。

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)

select *を実行すると、obj_typeobj_idがNULLになることが原因であることがかなり明らかです。2:

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

(それがNULLであることの確認):

postgres=# SELECT * FROM il2.objects WHERE obj_type IS NULL;
 obj_id | obj_type 
--------+----------
      2 | 

最初の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)
6
Randall

最初のSELECTの結果で空白行が返されるのはなぜですか?

NULLを任意の文字型(またはその他のほとんどの型、配列型は注目に値する例外)と連結すると、NULLが生成されるためです。関連:

NULLの表現は、クライアントによって異なります。いくつかのNULLをスペルアウトし、いくつかの(psqlを含む)代わりにnothingを使用します。多くの場合、それは構成可能です。

_obj_type::text_をキャストしても、空白行が表示されます。

NULLを(ほぼ)任意の型にキャストしても、別のデータ型のNULL-が返されます。

一部の行を挿入するために.sqlファイルに入れるVALUESテキストを作成するためのテキストを生成するクエリがあります。

COPY または psqlの同等の_\copy_ を検討しましたか?

その他の解決策

例が単純化されていない場合は、ROW値全体を選択するだけです。

_SELECT o  -- whole row
FROM   il2.objects o
WHERE  obj_id < 11
ORDER  BY obj_id;
_

特定の形式が必要な場合は、 format() を使用して簡単にします。すぐに使用できるNULL値を処理します。

_SELECT format('(%s, %L),', obj_id, obj_type)
FROM   objects;
_

NULL値の代わりにNULL(引用符で囲まれていない)を取得します(これは_''_とは異なり、区別する必要がある場合があります)。

db <> fiddle here(McNets、cudosの既存のフィドルに追加)

8

COALESCE関数を使用して、現在の値または空の文字列を返します。

SELECT '  (' || obj_id || ', ''' || coalesce(obj_type, '') || '''),' 
FROM   objects;
 | ?カラム? | 
 | :----------- | (1、 'val 1')、| 
 | (2、 '')、| 
 | (3、 'val 3')、| 
 | (4、 'val 4')、| 

db <> fiddle ---(ここ

11
McNets