PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Kiểm tra KHÔNG ĐẦY ĐỦ cho một bản ghi không trả về TRUE khi biến được đặt

Tôi thấy hai lý do có thể xảy ra, tại sao ...

Cả hai khoản tăng này đều không xuất hiện trong nhật ký tin nhắn của tôi

Chưa đăng nhập

Đầu tiên, một NOTICE thường không được ghi vào nhật ký cơ sở dữ liệu với cài đặt mặc định. Tôi trích dẫn sách hướng dẫn ở đây:

log_min_messages (enum )

Kiểm soát mức thông báo nào được ghi vào nhật ký máy chủ. Giá trị hợp lệ là DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATALPANIC . (...)
Giá trị mặc định là WARNING . Lưu ý rằng LOG ở đây có thứ hạng khác với ở client_min_messages .

Tôi nhấn mạnh đậm. Cũng lưu ý các mặc định khác (NOTICE ) cho client_min_messages (mục trước trong sách hướng dẫn).

Kiểm tra không hợp lệ

Thứ hai, hãy xem xét cách một biểu thức hàng được đánh giá. Kiểm tra row_variable IS NULL trả về TRUE nếu (và chỉ khi) mọi phần tử đơn lẻ NULL . Cho ví dụ sau:

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

Cả hai biểu thức trả về FALSE . Nói cách khác, một biến hàng (hoặc bản ghi) (1, NULL) không phải là NULL , cũng không phải là NOT NULL . Do đó, cả hai bài kiểm tra của bạn đều thất bại.

-> SQLfiddle với nhiều chi tiết hơn.

Thêm chi tiết, giải thích, liên kết và ứng dụng khả thi cho hành vi này trong CHECK ràng buộc trong câu trả lời có liên quan này:
Ràng buộc KHÔNG ĐẦY ĐỦ trên một tập hợp các cột

Bạn thậm chí có thể gán một biến bản ghi với NULL (rec := NULL ), kết quả là mọi phần tử đều là NULL - nếu kiểu là kiểu hàng nổi tiếng. Nếu không, chúng tôi đang xử lý một bản ghi ẩn danh và cấu trúc không được xác định và bạn không thể truy cập các phần tử để bắt đầu. Nhưng đó không phải là trường hợp với rowtype như trong ví dụ của bạn (luôn được nhiều người biết đến).

Giải pháp:FOUND

Cách chính xác để kiểm tra nếu bạn nhận được một hàng từ SELECT * INTO ?

Bạn phải xem xét rằng hàng có thể là NULL, ngay cả khi nó đã được chỉ định. Truy vấn rất có thể đã trả về một loạt các giá trị NULL (nếu định nghĩa bảng trong truy vấn của bạn cho phép các giá trị NULL). Thử nghiệm như vậy sẽ không đáng tin cậy theo thiết kế.

Có một cách tiếp cận đơn giản và an toàn. Sử dụng GET DIAGNOSTICS ... hoặc (nếu có) biến đặc biệt 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;

Chi tiết trong sách hướng dẫn.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. psql - lưu kết quả của lệnh vào một tệp

  2. Hai SQL LEFT JOINS tạo ra kết quả không chính xác

  3. Mẹo quản lý PostgreSQL từ xa

  4. Truy vấn số lượng các giá trị riêng biệt trong một phạm vi ngày luân phiên

  5. cron job để xóa dữ liệu cũ khỏi postgres trên debian