คอลัมน์“ ชื่อ” เวทมนต์มาจากไหน?


11

ฉันได้รับสิ่งนี้โดยไม่ได้ตั้งใจ:

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)

เคียวรีที่สองส่งคืน tuple ที่มีทั้งแถว ใช้ postgres 9.0.1

แก้ไข: คำจำกัดความของเว็บไซต์ตามคำขอ ฉันไม่สำคัญเลย, เรื่องแปลกประหลาดนี้ใช้ได้กับทุกโต๊ะ

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

siteมันจะช่วยในการแสดงความหมายของ
Peter Eisentraut

~ มันไม่สำคัญเพราะตอนนี้เราจะเห็นได้ว่าไม่มี "ชื่อ" ในsiteการเริ่มต้นด้วย เหตุใดคุณจึงต้องค้นหาคอลัมน์ที่ไม่มีอยู่
jcolebrand

1
ลองselect site from site- นี่จะช่วยให้คุณเข้าใจคำตอบของ Gaius อย่างละเอียด
แจ็คพูดว่าลอง topanswers.xyz

คำตอบ:


11

NAMEเป็นจริงเป็นฟังก์ชั่น มันเป็นมุมแหลมของ Postgres ว่าการทำงานกับคนเช่นอาร์กิวเมนต์ยังสามารถเรียกว่าเป็นfunction(arg) arg.functionจากเอกสาร:

ความเท่าเทียมกันระหว่างสัญกรณ์การทำงานและสัญกรณ์แอตทริบิวต์ทำให้เป็นไปได้ที่จะใช้ฟังก์ชั่นในประเภทคอมโพสิตเพื่อเลียนแบบ "เขตข้อมูลจากการคำนวณ"

NAMEเป็นชนิดภายในสำหรับชื่อวัตถุและฟังก์ชันนี้กำลังส่งอาร์กิวเมนต์ไปยังประเภทนั้นและส่งคืน


ขอบคุณฉันไม่รู้ สิ่งที่รบกวนจิตใจฉันหากฟังก์ชั่น "ชื่อ" นี้มีการบันทึกไว้ที่ใด?
hegemon

อัปเดตคำตอบของฉัน
Gaius

2
แม่นยำมากขึ้นในrowประเภทนี้จะถูกโยนไปเพราะเห็นว่าเป็นประเภทการป้อนข้อมูลของฟังก์ชันtext ฟังก์ชั่นแปลงแล้ว (ไม่หล่อ) สายป้อนชนิด(ซึ่งจะมีผลข้างเคียงของการตัดทอนถึง 64 ไบต์)namenamename
แจ็คกล่าวว่าพยายาม topanswers.xyz

3

นอกจากนี้โปรดทราบว่าการโยนชื่อโดยนัยถูกลบใน PostgreSQL 8.3 ซึ่งหมายความว่าพฤติกรรมนี้ไม่สามารถใช้งานได้อีกต่อไป แทบเป็นไปไม่ได้เลยที่จะเกิดพฤติกรรมนี้ใน PostgreSQL 8.3 และสูงกว่าโดยไม่ได้ตั้งใจเพราะสิ่งอันดับจะไม่แปลงเป็นข้อความโดยอัตโนมัติ

ดังนั้นใน 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;

แต่เพื่อให้ได้พฤติกรรมนั้นเราจะต้อง:

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

หรือเราสามารถกำหนดฟังก์ชั่นชื่อของเราเองในรูปแบบ comp_table_test และคืนสิ่งที่เราต้องการ


ฉันไม่เข้าใจคำตอบนี้ คุณกำลังบอกว่าคำถามที่ถูกวางไว้ด้านบนไม่ควรเป็นปัญหาอีกต่อไปสำหรับ 8.3 หรือสูงกว่า? ยังคำถามถามเกี่ยวกับ 9.0
Colin 't Hart

0

"ชื่อ" เป็นคำสำคัญที่สงวนไว้ ดังนั้นคุณควร "อ้าง" คำหลักเพื่อใช้:

SELECT "name" FROM site;

สิ่งนี้ได้แก้ไขปัญหาเหล่านี้บางอย่างให้ฉันในอดีตรหัสที่คุณโพสต์ควรทำงานโดยไม่ต้องอ้างถึง ในทางกลับกัน

select site.name from site;

คำเนื่องจากคุณใช้สคีมาเพื่อระบุชื่อคอลัมน์อย่างชัดเจน


1
สามารถใช้คำที่สงวนไว้ได้จำนวนมากและในกรณีนี้การอ้างอิงไม่ได้ช่วย นี่เป็นเพราะหาก site.name ไม่มีอยู่ในคอลัมน์ก่อนหน้า 8.3 สิ่งที่จะเกิดขึ้นคือคุณจะเริ่มมองหาฟังก์ชั่นชื่อที่ใช้ในประเภทข้อมูลไซต์หรือประเภทที่ส่งโดยปริยายจากไซต์ เนื่องจากไซต์สามารถส่งข้อความได้โดยปริยายจึงใช้ชื่อ (ข้อความ) ดังนั้นselect site.name from siteอาจมีการเปลี่ยนแปลงโดยนัยselect name(site::text) from siteซึ่งเป็นที่มาของเวทมนตร์
Chris Travers
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.