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
,FATAL
vàPANIC
. (...)
Giá trị mặc định là WARNING . Lưu ý rằngLOG
ở đâ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ẻ 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.