Thực sự có ba câu hỏi trong đó mà tôi sẽ cố gắng trả lời.
-
Mục đích của
unknownlà gì ?Đây là kiểu dữ liệu ban đầu được gán cho NULL và chuỗi ký tự trong câu lệnh SQL. Nếu các ký tự như vậy được gán, hãy nhập loại
textngay lập tức, sẽ rất khó để suy ra loại chính xác.Ví dụ:bạn muốn
myfunc('hello')để gọimyfunc(character varying), nhưng không có kiểu ẩn nào được truyền từtextký tựcharacter varying(và nó sẽ gây ra sự mơ hồ nếu bạn đã tạo). -
Tại sao
SELECT nulltrả về một cột thuộc loạiunknown?Câu trả lời truyền thống là:Bởi vì người dùng không chỉ định loại.
Tuy nhiên, hành vi này đã có vấn đề. Ví dụ:nếu bạn tạo một bảng như sau:
CREATE TABLE test AS SELECT 'hello';bạn sẽ kết thúc với một cột thuộc loại
unknown, không thể sử dụng được và sẽ gây ra nhiều vấn đề hơn nữa. Loạiunknownthực sự không nên để người dùng nhìn thấy, mà là chi tiết triển khai.Do đó, cam kết này đã thay đổi hành vi từ PostgreSQL v10 trên:Bây giờ là bất kỳ
unknownnào s còn lại trong mộtSELECThoặcRETURNINGdanh sách buộc phảitextvà không thể tạo bảng với các cột thuộc loạiunknown. -
Tại sao
SELECT NULL UNION SELECT 42hoạt động, nhưng không hoạt độngSELECT NULL UNION SELECT NULL UNION SELECT 42?Điều này là do quy tắc chuyển đổi loại .
UNIONđược kết hợp trái, vì vậy truy vấn sau này được hiểu là(SELECT NULL UNION SELECT NULL) UNION SELECT 42;Bây giờ là
UNIONđầu tiên phân giải thành kiểu dữ liệutextvì quy tắc 3:Điều này gây ra lỗi khi cố gắng giải quyết loại cho
UNIONthứ hai vì quy tắc 4:Mặt khác, trong truy vấn
SELECT NULL UNION SELECT 42;“NULL” có loại
unknownvà “42” có loạiinteger(kiểu được chọn cho các ký tự số không có dấu thập phân).Quy tắc 5
không áp dụng ở đây, vì
integerkhông phải là loại ưu tiên trong danh mục của nó (đó sẽ làoidvàdouble precision), vì vậy quy tắc 6 được sử dụng:Điều này dẫn đến một loại
integer.