PostgreSQL查询中未知的返回类型


9

以下查询有效:

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

a b
_ _
1 2
3 2

但是,我无法使用其他列类型,例如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.

似乎在第二种情况下,列类型被推断为unknown,但不会varchar(255)自动转换为。

我如何使第二个示例工作并返回正确类型的列,如果可能的话,不发出警告且不修改ARRAY[...]定义?

背景:我正在尝试使用psycopg2Python模块提高大容量插入操作的性能,该模块不支持在VALUES参数中使用多个行。在尝试其他方法时,我偶然发现了上面的示例。


我不确定为什么您声明psycopg2不支持中的多行VALUES。以下工作对我而言正好:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones,

我的意思是它不支持任意数量的行,例如cur.execute('INSERT INTO too VALUES %s', (list_of_rows,)),不存在这样的东西。
FX

嗯,我希望您将数组替换为单个参数。
戴夫·琼斯

Answers:


7

通过创建类型并将其强制转换为记录,您可以在不生成警告的情况下执行此操作:

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

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

在9.4和9.3上测试(这里是 db <> fiddle )


7

这很丑陋,但是您可以尝试:

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

这样,中定义的类型AS与的输出匹配unnest(),您可以将其转换为SELECT列表中的需求。

您可以在一个小型SQLFiddle中尝试此操作


1

应该这样做:

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

1
这行得通,但是我无法psycopg2强制在ARRAY[...]定义中包括类型强制转换。有没有可能做到这一点?我编辑了问题以反映这一点。
FX
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.