Ketik yang dikembalikan tidak dikenal dalam kueri PostgreSQL

9

Kueri berikut berfungsi:

SELECT a, b
FROM unnest(ARRAY[(1,2), (3,4)])
AS t(a integer, b integer);

a b
_ _
1 2
3 2

Namun, saya tidak dapat menggunakan jenis kolom yang berbeda seperti varchar(255):

SELECT a, b
FROM unnest(ARRAY[(1,'hello'), (3,'world')])
AS t(a integer, b varchar(255));

ERROR:  42804: function return row and query-specified return row do not match
DETAIL:  Returned type unkown at ordinal position 2, but query expects text.

Tampaknya, dalam kasus kedua, jenis kolom disimpulkan sebagai unknown, yang tidak dilemparkan ke varchar(255)otomatis.

Bagaimana saya membuat contoh kedua berfungsi dan mengembalikan kolom dengan tipe yang tepat, jika mungkin tanpa peringatan dan tanpa mengubah ARRAY[...]definisi?

Latar Belakang: Saya mencoba untuk meningkatkan kinerja operasi penyisipan massal besar menggunakan psycopg2modul Python, yang tidak mendukung penggunaan beberapa baris dalam VALUESargumen. Saya menemukan contoh di atas ketika mencoba beberapa metode lain.

FX
sumber
Saya tidak yakin mengapa Anda menyatakan bahwa psycopg2 tidak mendukung banyak baris VALUES. Berikut ini berfungsi dengan baik untuk saya:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones
Maksud saya adalah bahwa itu tidak mendukung jumlah baris yang sewenang-wenang, misalnya sesuatu seperti cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))tidak ada.
FX
Ahh, dan Anda berharap untuk mengganti array sebagai parameter tunggal, saya mengerti.
Dave Jones

Jawaban:

7

Anda bisa melakukan ini tanpa membuat peringatan dengan membuat tipe dan melemparkan catatan ke sana:

create type t as (a integer, b varchar(255));

select * from unnest(array[(1,'hello'), (3,'world')]::t[]);
┌───┬───────┐
 a    b   
├───┼───────┤
 1  hello 
 3  world 
└───┴───────┘

diuji pada 9.4 dan 9.3 (db <> biola di sini )

Jack mengatakan coba topanswers.xyz
sumber
7

Itu jelek, tetapi Anda dapat mencoba:

SELECT a, b::text
FROM unnest(ARRAY[(1,'hello'), (3,'world')])
AS t(a integer, b unknown);

Dengan cara ini tipe yang didefinisikan ASsesuai dengan output unnest(), yang dapat Anda gunakan untuk kebutuhan Anda dalam SELECTdaftar.

Anda dapat mencoba ini di SQLFiddle kecil .

dezso
sumber
1

Haruskah melakukannya:

SELECT a, b
FROM unnest(ARRAY[(1,varchar 'hello'), (3,varchar 'world')])
AS t(a integer, b varchar(255));
JoseTeixeira
sumber
1
Ini berfungsi, namun saya tidak dapat memaksa psycopg2untuk memasukkan tipe gips ke dalam ARRAY[...]definisi. Apakah mungkin melakukannya tanpa? Saya mengedit pertanyaan saya untuk mencerminkan hal itu.
FX