Hiểu về chức năng hoàn trả (SRF) trong danh sách CHỌN


8

Tại sao có sự khác biệt về hành vi giữa việc sử dụng Hàm Đặt lại (SRF) trong danh sách CHỌN so với sử dụng SRF trong mệnh đề TỪ?

Ví dụ: đối với SRF đơn giản trả về 2 hàng:

CREATE OR REPLACE FUNCTION gen_series(out integer, out int)
  RETURNS SETOF record AS $$
  SELECT 1,1
  UNION
  SELECT 2,2;
$$ LANGUAGE SQL;

SELECT gen_series(); trả về hai hàng cột đơn mỗi hàng chứa một bản ghi:

=>  gen_series 
------------
 (1,1)
 (2,2)
(2 rows)

Trong khi đó SELECT * FROM gen_series();trả về hai hàng với bản ghi được mở rộng:

=>  column1 | column2 
---------+---------
       1 |       1
       2 |       2
(2 rows)

Khi so sánh, nếu SRF trả về một cột đơn, thì việc gọi SRF trong mệnh đề CHỌN hoặc TỪ không có sự khác biệt. ví dụ:

=> SELECT generate_series(1,2);
 generate_series 
-----------------
               1
               2
(2 rows)

=> SELECT * FROM generate_series(1,2);
 generate_series 
-----------------
               1
               2
(2 rows)

Câu hỏi của tôi là:

  1. Tôi không hiểu tại sao trong trường hợp thứ hai, hành vi SRF khác với trường hợp đầu tiên chỉ vì bảng được trả về có một cột duy nhất. Đây có phải là hành vi thực sự phù hợp về các loại, bộ và bộ?

  2. Sự khác biệt giữa hai trường hợp dẫn đến hành vi khác nhau là gì?

  3. SRF có thể được sử dụng như các bảng như hình trên, nhưng các bảng có thể được sử dụng để thay thế SRF không? ví dụ

    SELECT my_table; 

Rõ ràng, điều này không thể được thực hiện, nhưng tại sao SELECT my_SRF();có thể, trong khi SELECT my_table;không được phép (về mặt quan hệ và toán học)?


SELECT my_table;không phải là một cú pháp hợp lệ
Mladen Uzelac

Câu trả lời:


3

Postgres đối xử với các trường hợp đơn giản khác nhau. Nhiều cột được coi là kiểu hỗn hợp (hàng bảng), chỉ được phân tách bằng SELECT * FROM ..., trong khi một cột kiểu vô hướng được xử lý như vậy, không có trình bao bọc kiểu hỗn hợp bổ sung. Vì vậy, SELECT my_SRF()sản xuất giống như SELECT * FROM my_SRF()cho trường hợp đơn giản. Hướng dẫn về Chức năng Bảng :

Các hàm bảng là các hàm tạo ra một tập hợp các hàng, được tạo thành từ các kiểu dữ liệu cơ sở (kiểu vô hướng) hoặc kiểu dữ liệu tổng hợp (các hàng của bảng).

Tôi đồng ý điều này là khó hiểu, và bạn không phải là người đầu tiên bị nhầm lẫn. (Tuy nhiên, hãy xem xét lựa chọn thay thế: việc thêm một trình bao bọc loại tổng hợp xung quanh một cột có thể còn khó hiểu hơn nữa.)

Nhưng không khó hiểu như những gì xảy ra khi bạn kết hợp nhiều chức năng SRF trong SELECTdanh sách. Điều này sẽ thay đổi với Postgres 10, mặc dù:

Cách an toàn, ít gây nhầm lẫn cho cả hai trường hợp là di chuyển các hàm SRF sang FROMmệnh đề. Sử dụng LATERALnối nếu bạn cần tham khảo các cột từ bảng khác. Hướng dẫn gợi ý:

Các LATERALcú pháp tạo ra kết quả ít ngạc nhiên khi gọi nhiều chức năng thiết lập trở lại, và thường nên được sử dụng để thay thế.

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.