Làm thế nào để truyền một hàng làm tham số cho hàm Postgres?


9

Tôi có một hàm build_details (), lấy một trong các tham số của nó, một hàng / bản ghi từ một bảng khác.

Đây là những gì tôi muốn làm, nhưng nó không hoạt động:

SELECT build_details(
    SELECT * FROM my_table LIMIT 1,
    1000,
    TRUE)

Tôi muốn lấy một hàng từ my_table và chuyển nó vào hàm để tôi có thể làm cho nó chạy. Làm cách nào để gọi hàm từ thiết bị đầu cuối với bản ghi từ my_table?

Câu trả lời:


8

Nó đơn giản hơn nhiều đó. Trong khi người ta mong đợi nó sẽ ...

SELECT build_details(my_table.*, 1000, TRUE) FROM my_table LIMIT 1;

... cú pháp thực tế là:

SELECT build_details(my_table, 1000, TRUE) FROM my_table LIMIT 1;

Tôi vừa kết hợp các câu trả lời của chúng tôi lại với nhau vừa thấy cửa sổ bật lên này, tôi đã trả lời và không nhận ra câu trả lời của bạn đã sử dụng đối tượng hàng và tôi không muốn gank nó. Bạn đánh tôi đến đấm.
Evan Carroll

Tại sao bạn làm điều đó trên trái đất?
Eduardo

1
@EvanCarrollQWERHJKL Tôi không biết bạn đã cố gắng thực hiện điều gì bằng cách thay thế câu trả lời của tôi bằng câu trả lời của bạn, nhưng tôi chỉ đặt mọi thứ trở lại như trước khi bạn nói đùa.
Eduardo

tuyệt, tôi sẽ chỉ gửi của riêng tôi sau đó. =) Về cơ bản là cùng một phương pháp, ngoại trừ được giải thích.
Evan Carroll

6

Tôi sẽ làm nó như thế này,

SELECT *
FROM my_table
CROSS JOIN LATERAL build_details( my_table, 1000, true )
LIMIT 1;

Bạn có thể thấy điều này làm việc với một số dữ liệu mẫu dưới đây.

-- create some sample data,
CREATE TABLE foo(bar)
  AS VALUES (42::int), (7);

-- select a row object, representing every row in foo;
SELECT foo 
FROM foo;

Tạo một hàm lấy một kiểu hàngfoobool và a intvà chỉ cần đưa ra một thông báo và trả về true.

CREATE FUNCTION build_details( myrow foo, j int, k bool )
RETURNS bool AS $$
  BEGIN
    RAISE NOTICE '%, %, %', myrow, j, k;
    RETURN true;
  END;
$$ LANGUAGE plpgsql;

Bây giờ chúng ta có thể sử dụng cú pháp trên để truyền đối tượng hàng đại diện cho một hàng foo, với hai biến khác là inta và a bool.

SELECT *
FROM foo
CROSS JOIN LATERAL build_details(foo::foo, 1000, true);
NOTICE:  (42), 1000, t
NOTICE:  (7), 1000, t
 bar | build_details 
-----+---------------
  42 | t
   7 | t
(2 rows)

Tất nhiên, bạn vẫn có thể sử dụng LIMIThoặc bất kỳ vị từ nào bạn muốn.


1
Lưu ý rằng đó SELECT * FROM foo, build_details(foo, 1000, true)là một phím tắt truy vấn cuối cùng. Nó không tham gia một bên ngầm.
pbillen

1
Tôi tình cờ tìm thấy câu trả lời này một cách tình cờ khi cố gắng tìm ra lý do tại sao tôi không thể gọi select some_func(foo.*)...để gửi hàng của mình đến chức năng. Bí mật là select some_func(foo::foo).... Cảm ơn!
Phil

@Phil Hàng đã được gõ vào bảng, lần duy nhất bạn cần là nếu bạn muốn chuyển một loại hàng sang một loại hàng khác.
Evan Carroll

Đó là những gì tôi hy vọng. Thật không may, tôi cần phải đúc nó một cách rõ ràng. Lạ nhưng đúng trong trường hợp cụ thể của tôi.
Phil

3

Sử dụng một mục chọn để chọn lại hàng

Điều này dường như làm việc:

SELECT * FROM public.build_details(
    (SELECT r.*::public.my_table FROM (TABLE public.my_table) r LIMIT 1),
    1000,
    TRUE);
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.