Bu ilginç bir bulgu. Normalde, burada görebileceğiniz gibi, bir NULL varsayılan veri türüne sahip değildir:
SELECT pg_typeof(NULL);
pg_typeof
───────────
unknown
Bir VALUES
tablo resme geldiğinde bu değişir :
SELECT pg_typeof(core) FROM (
VALUES (NULL)
) new_values (core);
pg_typeof
───────────
text
Bu davranış, kaynak kodunda https://doxygen.postgresql.org/parse__coerce_8c.html#l01373 adresinde açıklanmıştır :
/*
* If all the inputs were UNKNOWN type --- ie, unknown-type literals ---
* then resolve as type TEXT. This situation comes up with constructs
* like SELECT (CASE WHEN foo THEN 'bar' ELSE 'baz' END); SELECT 'foo'
* UNION SELECT 'bar'; It might seem desirable to leave the construct's
* output type as UNKNOWN, but that really doesn't work, because we'd
* probably end up needing a runtime coercion from UNKNOWN to something
* else, and we usually won't have it. We need to coerce the unknown
* literals while they are still literals, so a decision has to be made
* now.
*/
(Evet, mükemmel yorumlar sayesinde PostgreSQL kaynak kodunun anlaşılması nispeten kolaydır ve çoğu yerde bulunur.)
Ancak çıkış yolu şu olabilir. Diyelim ki her zaman VALUES
belirli bir tablonun tüm sütunlarıyla eşleşiyorsunuz (diğer durumlar için aşağıdaki ikinci nota bakın). Örneğin, küçük bir hile muhtemelen yardımcı olabilir:
SELECT (x).* FROM (VALUES ((TRUE, NULL, 1234)::fields)) t(x);
active │ core │ id
────────┼──────┼──────
t │ │ 1234
Burada tablonun türüne dökülen satır ifadelerini kullanır ve sonra bunları bir tabloya geri çıkarırsınız.
Yukarıdaki dayanarak, senin UPDATE
gibi görünebilir
UPDATE fields AS t set active = (x).active, core = (x).core
FROM ( VALUES
((true, NULL, 3419)::fields),
((false, NULL, 3420)::fields)
) AS new_values(x) WHERE (x).id = t.id;
Notlar:
- Daha iyi insan okunabilirliği için çift tırnak işaretlerini kaldırdım, ancak (sütun) adları oluştururken yardımcı oldukları gibi tutabilirsiniz.
- yalnızca sütunların bir alt kümesine ihtiyacınız varsa, bu amaçla özel türler oluşturabilirsiniz . Onları yukarıdaki gibi kullanın (burada otomatik olarak tablo ile oluşturulan türü, ikincisinin satır yapısını tutarak).
Dbfiddle üzerinde çalışan her şeye bakın .
Cannot cast type boolean to bigint in column 1
(ilk alanlar ifadesi arasında :: hata noktaları)