PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Tes IS NOT NULL untuk catatan tidak mengembalikan TRUE ketika variabel disetel

Saya melihat dua kemungkinan alasan, mengapa ...

Tak satu pun dari kenaikan gaji ini muncul di log pesan saya

Tidak dicatat

Pertama, sebuah NOTICE biasanya tidak ditulis ke log database dengan pengaturan default. Saya mengutip manualnya di sini:

log_min_messages (enum )

Mengontrol level pesan mana yang ditulis ke log server. Nilai yang valid adalah DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATAL , dan PANIC . (...)
Defaultnya adalah PERINGATAN . Perhatikan bahwa LOG memiliki peringkat yang berbeda di sini daripada di client_min_messages .

Penekanan saya yang berani. Perhatikan juga default yang berbeda (NOTICE ) untuk client_min_messages (item sebelumnya dalam manual).

Tes tidak valid

Kedua, pertimbangkan bagaimana ekspresi baris dievaluasi. Pengujian row_variable IS NULL mengembalikan TRUE if (dan hanya jika) setiap elemen adalah NULL . Diberikan contoh berikut:

SELECT (1, NULL) IS NULL AS a     -- FALSE
      ,(1, NULL) IS NOT NULL AS b -- also FALSE

Keduanya ekspresi mengembalikan FALSE . Dengan kata lain, variabel baris (atau record) (1, NULL) bukan NULL , juga bukan NOT NULL . Oleh karena itu, kedua pengujian Anda gagal.

-> SQLfiddle dengan lebih detail.

Detail lebih lanjut, penjelasan, tautan, dan kemungkinan aplikasi untuk perilaku ini di CHECK batasan dalam jawaban terkait ini:
NOT NULL batasan pada sekumpulan kolom

Anda bahkan dapat menetapkan variabel record dengan NULL (rec := NULL ), yang menghasilkan setiap elemen menjadi NULL - jika tipenya adalah tipe baris yang terkenal. Jika tidak, kita berurusan dengan catatan anonim dan strukturnya tidak ditentukan dan Anda tidak dapat mengakses elemen untuk memulai. Tapi tidak demikian halnya dengan rowtype seperti dalam contoh Anda (yang selalu terkenal).

Solusi:FOUND

Apa cara yang benar untuk menguji jika Anda menerima baris dari SELECT * INTO ?

Anda harus mempertimbangkan bahwa baris tersebut dapat berupa NULL, meskipun telah ditetapkan. Kueri bisa saja mengembalikan banyak nilai NULL (jika definisi tabel dalam kueri Anda mengizinkan nilai NULL). Tes seperti itu secara desain tidak dapat diandalkan.

Ada pendekatan yang sederhana dan aman. Gunakan GET DIAGNOSTICS ... atau (jika ada) variabel khusus FOUND :

SELECT * FROM my_table WHERE owner_id = 6 INTO my_var;

IF NOT FOUND THEN
   RAISE NOTICE 'Query did not return a row!';
END IF;

Detail dalam manual.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. apa itu @JoinColumn dan bagaimana menggunakannya di Hibernate

  2. Bagaimana cara memigrasi Tabel Postgres yang ada ke tabel yang dipartisi setransparan mungkin?

  3. Mendapatkan NoSuchMethodError:javax.persistence.Table.indexes() saat melakukan kueri JPA

  4. IN Klausa dengan NULL atau IS NULL

  5. Izinkan null di kolom unik