web-dev-qa-db-fra.com

Type retourné inconnu dans la requête PostgreSQL

La requête suivante fonctionne:

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

a b
_ _
1 2
3 2

Cependant, je n'ai pas pu utiliser de type colonne différent tel que 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.

Il semble que, dans le second cas, le type de colonne est déduit sous la forme unknown, qui n'est pas distribué à varchar(255) automatiquement.

Comment faire le deuxième exemple de travail et retourne des colonnes avec le bon type, si possible sans avertissements et sans modifier la définition ARRAY[...]?

Contexte: j'essaie d'améliorer les performances des grandes opérations d'insertion en vrac à l'aide du psycopg2 Python Module, qui ne prend pas en charge avec plusieurs lignes dans VALUES arguments. J'ai trébuché sur l'exemple ci-dessus tout en essayant d'autres méthodes.

9
F.X.

Vous pouvez le faire sans générer un avertissement en créant un type et en jetant les enregistrements.

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

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

testé sur 9.4 et 9.3 (dB <> violon ici )

C'est moche, mais vous pouvez essayer:

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

De cette façon, le type défini dans AS correspond à la sortie de unnest(), que vous pouvez lancer à vos besoins dans la liste SELECT.

Vous pouvez essayer cela dans un petit sqlfiddle .

7
dezso

Devrait le faire:

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