Tự động chuyển đổi các bản ghi ẩn danh được trả về từ UDF sang loại bảng nổi tiếng


8

Mã độc quyền (mà chúng ta không thể thay đổi) có một loạt các hàm do người dùng định nghĩa thuộc loại:

create or replace function f() returns record as $$ ... $$

mà chúng tôi gọi theo cách sau (ví dụ):

SELECT status, log FROM f() as (status boolean, log text);

(status boolean, log text)là một dãy bàn T. Có thể tự động chuyển đổi record(hoặc setof recordloại trả về) thành hàng Tmà không liệt kê các thuộc tính? Những gì tôi đang tìm kiếm là loại:

SELECT * FROM f() as T%rowtype

1
Nếu hàm không có đối số, bạn có thể gói nó vào dạng xem.
a_horse_with_no_name

1
Hoặc bạn cũng có thể bọc chúng thành các hàm trong một lược đồ khác nhưng một chữ ký giống hệt nhau. Hoặc nếu bạn biết nguồn, hãy tạo bộ chúng có thể sử dụng của riêng bạn.
dezso

Về mặt kỹ thuật, tôi nghĩ, những gì bạn đề xuất là không thể.
dezso

@dezso: Tôi tìm thấy một cách cho các hàm trả về một hàng đơn.
Erwin Brandstetter

@ErwinBrandstetter Có, và nó đơn giản như nó có thể, nhưng vẫn là một gói :). Việc gán đến và từ các biến bản ghi / hàng đầy bất ngờ.
dezso

Câu trả lời:


8

Có một cách.

Đưa ra một bảng tvà một hàm f()trả về một bản ghi ẩn danh phù hợp với loại bảng đó:

CREATE TABLE t (id int, d date);

Bạn không thể chỉ tạo bản ghi ẩn danh, vì danh sách định nghĩa cột là bắt buộc cho

SELECT * FROM f()

Trích dẫn hướng dẫn trên lệnh SELECT :

Nếu hàm đã được xác định là trả về kiểu dữ liệu bản ghi, thì phải có một bí danh hoặc từ khóa AS, theo sau là danh sách định nghĩa cột trong biểu mẫu ...

Nhấn mạnh đậm của tôi.

Vì vậy, trong khi tất cả các truy vấn này hoạt động:

SELECT '(1,2013-11-11)'::t;
SELECT ('(1,2013-11-11)'::t).*;
SELECT f();                      -- returning anonymous record
SELECT * FROM f() AS f(id int, d date);

Không ai trong số này làm:

SELECT * FROM f();
SELECT * FROM f()::t;

Cái sau đưa ra một ngoại lệ:

LRI: không thể truyền bản ghi loại tới t

Bạn có thể gói SELECTdanh sách định nghĩa cột vào một VIEWhoặc một hàm như @a_horse@deszo đề xuất. Điều đó sẽ làm việc tốt:

CREATE OR REPLACE VIEW v1 AS
SELECT * FROM f() AS f(id int, d date);

Nhưng điều đó sẽ không trả lời câu hỏi của bạn:

chuyển đổi bản ghi (hoặc loại trả về bản ghi setof) thành hàng Tmà không liệt kê các thuộc tính?

Giải pháp cho hàng đơn

Trong khi một diễn viên thất bại, một nhiệm vụ trong plpgsql hoạt động.

CREATE OR REPLACE function f1(OUT rec t) AS
$func$
BEGIN
rec := f();   -- assignment succeeds where cast failed (!)
END
$func$ LANGUAGE plpgsql;

Gọi:

SELECT * FROM f1();

Mặc dù bạn cũng có thể viết hàm trả về tập hợp với mẫu đó nhưng tôi không tìm thấy cách nào SELECTtừ hàm trả về tập mà không cung cấp danh sách định nghĩa cột ...

-> SQLfiddle


Cảm ơn rất nhiều cho câu trả lời. Giải pháp của bạn để "bỏ" chữ ký của UDF để nó truy xuất loại bảng (hàng) thay vì loại bản ghi hoạt động. Ngoài ra, tôi phải nói rằng tôi đã sử dụng thành công phương pháp này để trả về một bộ hồ sơ. Trong câu trả lời của bạn, người ta phải thay thế CREATE OR REPLACE function f1(OUT rec t) AS table typebằng CREATE OR REPLACE function f1() returns setof T as....
arthur

Câu hỏi được đăng là một sự đơn giản hóa của vấn đề ban đầu mà tôi thực sự có. Vấn đề ban đầu của tôi là hàm lấy một tham số kiểu regclasslàm đầu vào và trả về một setofbản ghi (loại hàng của lớp reg đầu vào tương ứng). Trong trường hợp này, tôi không thể tạo chức năng bao bọc vì loại trả về chỉ được biết tại thời điểm thực hiện, phải không?
arthur

@arthur: Đó là thứ khó khăn. Tôi đề nghị bạn tạo một câu hỏi mới với tất cả các chi tiết cần thiết. Bạn luôn có thể tham khảo cái này cho bối cảnh. Tôi nghĩ rằng tôi có một giải pháp cho điều đó ...
Erwin Brandstetter

@arthur: Tôi cũng sẽ rất quan tâm đến cách bạn quản lý CHỌN từ một hàm trả về đã đặt mà không cung cấp danh sách định nghĩa cột. Bạn có thể gửi một câu trả lời với một ví dụ mã ở đây?
Erwin Brandstetter

Tôi không có câu trả lời làm thế nào người ta có thể thực hiện một truy vấn chọn cho hàm trả về setof record. Tôi đã nghĩ đến các cách giải quyết có thể và tạo ra các giá trị chèn-giá trị-từ-một-bản ghi-biến-vào-một-bảng . chọn một hàm trả về setof Ttương đối đơn giản. Nhưng tôi cho rằng biểu hiện của bạn set retuning functionthực sự có nghĩa là setof record returning function...
arthur
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.