Kiểu trả về không xác định trong truy vấn PostgreSQL


9

Các truy vấn sau đây hoạt động:

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

a b
_ _
1 2
3 2

Tuy nhiên, tôi không thể sử dụng một loại cột khác, chẳng hạn như 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.

Có vẻ như, trong trường hợp thứ hai, loại cột được suy ra unknownlà không được varchar(255)tự động chuyển thành.

Làm cách nào để làm cho ví dụ thứ hai hoạt động và trả về các cột với đúng loại, nếu có thể mà không có cảnh báo và không sửa đổi ARRAY[...]định nghĩa?

Bối cảnh: Tôi đang cố gắng cải thiện hiệu suất của các hoạt động chèn số lượng lớn bằng psycopg2mô-đun Python, không hỗ trợ sử dụng nhiều hàng trong các VALUESđối số. Tôi vấp vào ví dụ trên trong khi thử một số phương pháp khác.


Tôi không chắc tại sao bạn nói rằng psycopg2 không hỗ trợ nhiều hàng VALUES. Những điều sau đây chỉ tốt cho tôi:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones

Ý tôi là nó không hỗ trợ số lượng hàng tùy ý, ví dụ như thứ gì đó cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))không tồn tại.
FX

Ahh, và bạn đang hy vọng thay thế mảng như một tham số duy nhất, tôi thấy.
Dave Jones

Câu trả lời:


7

Bạn có thể làm điều này mà không cần tạo cảnh báo bằng cách tạo một loại và truyền các bản ghi cho nó:

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

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

đã thử nghiệm vào ngày 9.4 và 9.3 (db <> fiddle tại đây )


7

Thật là xấu xí, nhưng bạn có thể thử:

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

Bằng cách này, loại được xác định ASphù hợp với đầu ra của unnest(), mà bạn có thể sử dụng theo nhu cầu của mình trong SELECTdanh sách.

Bạn có thể thử điều này trong một SQLFiddle nhỏ .


1

Hãy làm nó:

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

1
Điều này hoạt động, tuy nhiên tôi không thể buộc psycopg2bao gồm các kiểu phôi trong ARRAY[...]định nghĩa. Có thể làm điều đó mà không cần? Tôi đã chỉnh sửa câu hỏi của mình để phản ánh điều đó.
FX
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.