Trường hợp cột ma thuật tên Tử đến từ đâu?


11

Tôi đã nhận được điều này một cách tình cờ:

db=> select name from site;
ERROR:  column "name" does not exist
LINE 1: select name from site;
               ^
db=> select site.name from site;
     name
---------------
 (1,mysitename)
(1 row)

Truy vấn thứ hai trả về một tuple chứa toàn bộ một hàng. Sử dụng postgres 9.0.1.

Chỉnh sửa: định nghĩa của trang web theo yêu cầu. Tôi không thực sự quan trọng, quirk này hoạt động cho bất kỳ bảng.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null

Nó sẽ giúp hiển thị định nghĩa của site.
Peter Eisentraut

~ Nó không thành vấn đề bởi vì bây giờ chúng ta có thể thấy rằng không có "tên" siteđể bắt đầu. Tại sao bạn lại truy vấn một cột không tồn tại?
jcolebrand

1
Hãy thử select site from site- điều này sẽ giúp bạn hiểu câu trả lời của Gaius chi tiết hơn
Jack nói hãy thử topanswers.xyz

Câu trả lời:


11

NAMEthực sự là một chức năng . Đó là một sự châm biếm của Postgres rằng một hàm có một đối số, ví dụ function(arg)cũng có thể được gọi là arg.function. Từ các tài liệu:

Sự tương đương giữa ký hiệu chức năng và ký hiệu thuộc tính cho phép sử dụng các hàm trên các loại hỗn hợp để mô phỏng "các trường được tính toán".

NAMElà một kiểu nội bộ cho các tên đối tượng và hàm này đang truyền đối số của nó cho kiểu đó và trả về nó.


Cảm ơn, tôi không biết điều đó. Điều gì làm phiền tôi, nếu chức năng đặc biệt này "tên" được ghi lại ở bất cứ đâu?
bá chủ

Cập nhật câu trả lời của tôi
Gaius

2
Chính xác hơn, rowloại đang được truyền tới textvì đó là loại đầu vào của hàm name. Sau đó, namehàm sẽ chuyển đổi (không truyền) chuỗi đầu vào thành loại name(cũng sẽ có tác dụng phụ là cắt ngắn thành 64 byte)
Jack nói hãy thử topanswers.xyz

3

Cũng lưu ý rằng việc chuyển đổi ẩn thành tên đã bị xóa trong PostgreSQL 8.3, có nghĩa là hành vi này không còn hoạt động. Hầu như không thể vô tình có được hành vi này trong PostgreSQL 8.3 trở lên vì các bộ dữ liệu không tự động chuyển đổi thành văn bản.

Vì vậy, trong 9.1:

or_examples=# select c.name from comp_table_test c;
ERROR:  column c.name does not exist
LINE 1: select c.name from comp_table_test c;

nhưng để có được hành vi đó, chúng ta phải:

or_examples=# select name(c::text) from comp_table_test c;

Hoặc chúng ta có thể định nghĩa hàm tên riêng của mình bằng kiểu comp_table_test và trả về bất cứ thứ gì chúng ta muốn.


Tôi không hiểu câu trả lời này. Bạn đang nói câu hỏi được đặt ra ở trên không nên là vấn đề nữa vào ngày 8.3 trở lên? Tuy nhiên, câu hỏi hỏi về 9.0
Colin 't Hart

0

"Tên" là một từ khóa dành riêng . Vì vậy, bạn nên "trích dẫn" từ khóa để sử dụng nó:

SELECT "name" FROM site;

Điều này đã giải quyết một số vấn đề này cho tôi trong quá khứ, mặc dù mã bạn đã đăng cũng sẽ hoạt động mà không cần trích dẫn. Mặt khác

select site.name from site;

từ vì bạn rõ ràng đang sử dụng lược đồ để phân giải tên của cột


1
Rất nhiều từ dành riêng có thể được sử dụng, và trong trường hợp này, nó trích dẫn không giúp ích gì. Điều này là do nếu site.name không tồn tại dưới dạng cột thì trước 8.3, điều gì sẽ xảy ra là bạn sẽ bắt đầu tìm kiếm các hàm tên trong một kiểu dữ liệu trang web hoặc một kiểu ngầm định từ trang web. Vì trang web có thể được chuyển hoàn toàn thành văn bản, tên (văn bản) sẽ được sử dụng. Do đó, select site.name from sitecó thể được chuyển đổi hoàn toàn sang select name(site::text) from sitenơi mà phép thuật bắt nguồn.
Chris Travers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.