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
unknown
là 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
text
ngay 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ừtext
ký tựcharacter varying
(và nó sẽ gây ra sự mơ hồ nếu bạn đã tạo). -
Tại sao
SELECT null
trả 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ạiunknown
thự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ỳ
unknown
nào s còn lại trong mộtSELECT
hoặcRETURNING
danh sách buộc phảitext
và không thể tạo bảng với các cột thuộc loạiunknown
. -
Tại sao
SELECT NULL UNION SELECT 42
hoạ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ệutext
vì quy tắc 3:Điều này gây ra lỗi khi cố gắng giải quyết loại cho
UNION
thứ hai vì quy tắc 4:Mặt khác, trong truy vấn
SELECT NULL UNION SELECT 42;
“NULL” có loại
unknown
và “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ì
integer
không phải là loại ưu tiên trong danh mục của nó (đó sẽ làoid
và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
.