Sihirli sütun “adı” nereden geliyor?


11

Bunu kazara aldım:

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)

İkinci sorgu tüm satırı içeren bir tuple döndürür. Postgres kullanımı 9.0.1.

Düzenle: sitenin istek üzerine tanımı. Gerçekten önemli değil, bu tuhaflık herhangi bir masa için çalışıyor.

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

Tanımını göstermeye yardımcı olur site.
Peter Eisentraut

~ O does şimdi hiç "ad" olduğunu görebilirsiniz, çünkü madde siteile başlayacak. Neden mevcut olmayan bir sütunu sorguluyorsunuz?
jcolebrand

1
Deneyin select site from site- bu Gaius'un cevabını daha ayrıntılı olarak anlamanıza yardımcı olacaktır
Jack diyor ki topanswers.xyz

Yanıtlar:


11

NAMEaslında bir işlevdir . Postgres'in bir tuhaflığı, örneğin bir argümanla bir işlevin function(arg)aynı zamanda olarak adlandırılabilmesidir arg.function. Dokümanlardan:

İşlevsel gösterim ve öznitelik gösterim arasındaki eşdeğerlik, "hesaplanan alanları" taklit etmek için bileşik türlerde işlevlerin kullanılmasını mümkün kılar.

NAMEBir olan nesne adları için iç tip ve bu fonksiyon bu tür kendi argümanını döküm ve onu geri dönüyor.


Teşekkürler, bunu bilmiyordum. Bu özel işlev "adı" herhangi bir yerde belgelenirse beni rahatsız eden nedir?
hegemon

Cevabım güncellendi
Gaius

2
Daha doğrusu, rowtipi döküm ediliyor textbu işlevin giriş türüdür çünkü name. nameFonksiyon sonra tipine giriş dizesi (döküm değil) dönüştürmektedir name(ayrıca 64 bayt kesiliyor yan etkisi olmaz)
Jak topanswers.xyz deneyin diyor

3

Ayrıca, isme örtük olarak isimlendirmenin PostgreSQL 8.3'te kaldırıldığını unutmayın, bu da bu davranışın artık çalışmadığı anlamına gelir. Bu davranışı kazara PostgreSQL 8.3 ve üstü ile elde etmek neredeyse imkansızdır çünkü tuples otomatik olarak metne dönüşmez.

Yani 9.1'de:

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;

ama bu davranışı elde etmek için:

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

Ya da comp_table_test türünü alarak ve istediğimizi döndürerek kendi ad fonksiyonumuzu tanımlayabiliriz.


Bu cevabı anlamıyorum. Yukarıda sorulan sorunun 8.3 ya da üstü sürümlerde sorun olmaması gerektiğini mi söylüyorsunuz? Yine de soru 9.0
Colin 't Hart

0

"name" ayrılmış bir anahtar kelimedir . Dolayısıyla, anahtar kelimeyi kullanmak için "alıntı yapmanız" gerekir:

SELECT "name" FROM site;

Bu, yayınladığınız kodun da alıntı yapmadan çalışmasına rağmen, geçmişte benim için bu sorunların bazılarını çözdü. Diğer yandan

select site.name from site;

çünkü sütunun adını çözmek için şemayı açıkça kullanıyorsunuz


1
Çok fazla ayrılmış kelime kullanılabilir ve bu durumda alıntı yapmak yardımcı olmaz. Bunun nedeni, site.name bir sütun olarak mevcut değilse, 8.3'ten önce, bir site veri türünde veya örtük olarak siteden yayınlanan bir türde ad işlevlerini aramaya başlamanızdır . Site dolaylı olarak metne dönüştürülebildiğinden, ad (metin) kullanılır. Sonuç select site.name from siteolarak, örtülü select name(site::text) from siteolarak büyünün geldiği yere dönüştürülebilir .
Chris Travers
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.