Rumah > pangkalan data > tutorial mysql > Bagaimana Mengendalikan Nilai NULL Apabila Mengemas kini Berbilang Baris dalam PostgreSQL?

Bagaimana Mengendalikan Nilai NULL Apabila Mengemas kini Berbilang Baris dalam PostgreSQL?

Susan Sarandon
Lepaskan: 2025-01-03 14:41:43
asal
572 orang telah melayarinya

How to Handle NULL Values When Updating Multiple Rows in PostgreSQL?

Memutuskan NULL Apabila Mengemas kini Berbilang Baris

Apabila mengemas kini berbilang baris dalam jadual menggunakan satu pertanyaan, adalah penting untuk memastikan bahawa nilai itu berada yang ditetapkan sepadan dengan jenis data lajur yang terlibat. Jika nilai NULL terlibat, ini boleh menyebabkan ralat disebabkan oleh ketidakpadanan jenis.

Gambaran Keseluruhan Isu

Pertimbangkan pertanyaan berikut:

UPDATE foo SET x=t.x, y=t.y
FROM (
  VALUES (50, 50, 1),
         (100, 120, 2)
)
AS t(x, y, pkid)
WHERE foo.pkid=t.pkid
Salin selepas log masuk

Pertanyaan ini berfungsi untuk nilai bukan NULL, tetapi apabila nilai NULL diperkenalkan, ralat berlaku:

UPDATE foo SET x=t.x, y=t.y
FROM (
  VALUES (null, 20, 1),
         (null, 50, 2)
)
AS t(x, y, pkid)
WHERE foo.pkid=t.pkid
Salin selepas log masuk

Ralat disebabkan oleh spesifikasi jenis yang hilang untuk nilai NULL. PostgreSQL cuba meneka jenisnya berdasarkan literal, mengakibatkan ketidakpadanan dengan lajur integer x.

Penyelesaian

Untuk menyelesaikan isu ini, beberapa penyelesaian boleh digunakan :

0. Pilih Baris dengan LIMIT 0, Tambah Baris dengan KESATUAN SEMUA NILAI

UPDATE foo f
SET    x = t.x
     , y = t.y
FROM  (
  (SELECT pkid, x, y FROM foo LIMIT 0) -- parenthesis needed with LIMIT
   UNION ALL
   VALUES
      (1, 20, NULL)  -- no type casts here
    , (2, 50, NULL)
   ) t               -- column names and types are already defined
WHERE  f.pkid = t.pkid;
Salin selepas log masuk

1. Pilih Baris dengan LIMIT 0, Tambah Baris dengan UNION ALL SELECT

UPDATE foo f
SET    x = t.x
     , y = t.y
FROM  (
  (SELECT pkid, x, y FROM foo LIMIT 0) -- parenthesis needed with LIMIT
   UNION ALL SELECT 1, 20, NULL
   UNION ALL SELECT 2, 50, NULL
   ) t               -- column names and types are already defined
WHERE  f.pkid = t.pkid;
Salin selepas log masuk

2. Ungkapan NILAI dengan Jenis Setiap Lajur

UPDATE foo f
SET    x = t.x
     , y = t.y
FROM  (
   VALUES 
     ((SELECT pkid FROM foo LIMIT 0)
    , (SELECT x    FROM foo LIMIT 0)
    , (SELECT y    FROM foo LIMIT 0))  -- get type for each col individually
   , (1, 20, NULL)
   , (2, 50, NULL)
   ) t (pkid, x, y)  -- columns names not defined yet, only types.
WHERE  f.pkid = t.pkid;
Salin selepas log masuk

3. Ungkapan NILAI dengan Jenis Baris

UPDATE foo f
SET x = (t.r).x         -- parenthesis needed to make syntax unambiguous
  , y = (t.r).y
FROM (
   VALUES
      ('(1,20,)'::foo)  -- columns need to be in default order of table
     ,('(2,50,)')       -- nothing after the last comma for NULL
   ) t (r)              -- column name for row type
WHERE  f.pkid = (t.r).pkid;
Salin selepas log masuk

4. Ungkapan NILAI dengan Jenis Baris Terurai

UPDATE foo f
SET    x = t.x
     , y = t.y
FROM (
   VALUES
      (('(1,20,)'::foo).*)  -- decomposed row of values
    , (2, 50, NULL)
   ) t(pkid, x, y)  -- arbitrary column names (I made them match)
WHERE  f.pkid = t.pkid;     -- eliminates 1st row with NULL values
Salin selepas log masuk

5. Ungkapan NILAI dengan Jenis Diambil daripada Jenis Baris

UPDATE foo f
SET   (  x,   y)
    = (t.x, t.y)  -- short notation, see below
FROM (
   VALUES
      ((NULL::foo).pkid, (NULL::foo).x, (NULL::foo).y)  -- subset of columns
    , (1, 20, NULL)
    , (2, 50, NULL)
   ) t(pkid, x, y)       -- arbitrary column names (I made them match)
WHERE  f.pkid = t.pkid;
Salin selepas log masuk

Pilihan penyelesaian bergantung pada faktor seperti prestasi, kemudahan dan bilangan lajur yang terlibat. Penyelesaian 4 dan 5 biasanya disyorkan untuk kesederhanaan dan fleksibiliti.

Atas ialah kandungan terperinci Bagaimana Mengendalikan Nilai NULL Apabila Mengemas kini Berbilang Baris dalam PostgreSQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan