2010-09-16 10 views
6

Nếu tôi cố gắng tạo cột có giá trị là lựa chọn trả về nhiều hàng, tôi gặp lỗi.PostgreSQL: Tại sao không thể truy vấn con dưới dạng biểu thức trả về nhiều hàng, nhưng chức năng có thể?

=> select (select 1 union select 2); 
ERROR: more than one row returned by a subquery used as an expression 

Nhưng nếu tôi tạo một chức năng thực hiện tương tự, tôi sẽ nhận được hành vi mà tôi muốn.

=> create or replace function onetwo() returns setof integer as $$ 
$> select 1 union select 2 
$> $$ language 'sql' strict immutable; 
CREATE FUNCTION 
=> select onetwo(); 
onetwo 
-------- 
     1 
     2 

Tại sao sự khác biệt?

Trả lời

4

Trong khi câu trả lời của OMG Ponies là hoàn toàn chính xác, tôi muốn đặt nó như sau: Bạn đang bối rối SELECT f() với SELECT literal.

  • SELECT f()thực hiện một hàm và trả về kết quả của nó. Và, một hàm trả về bảng cũng có thể được viết là SELECT * FROM f() - thậm chí còn thanh lịch hơn. Bởi vì Thạc vẫn chưa có các thủ tục lưu trữ - ít lịch trình họ có thể được thực hiện thông qua chức năng - chúng tôi sử dụng SELECT như Microsoft SQL sử dụng EXECUTE

  • SELECT LITERAL là một phương pháp trả lại một chữ (cái gì mà có thể phù hợp trong một hàng /cột).

+1

+1 và tôi nghĩ rằng tôi đã thấy biểu mẫu 'SELECT f()' (cho hàm trả về 'f') được mô tả như là một cú pháp cú pháp cho' SELECT * FROM f() '. Nó chỉ được thực hiện bởi vì nó rõ ràng và một cách viết tắt thuận tiện. – Edmund

5

Nó không phải là một quả táo để so sánh táo.

select * 
    FROM (select 1 
     union ALL 
     select 2) 

... tương đương với chức năng của bạn.

Cột trong mệnh đề SELECT chỉ có thể trả về một giá trị cho mỗi bản ghi. Điều này là không thể với ví dụ UNION của bạn. Vì vậy, tôi chuyển đổi nó thành một bảng có nguồn gốc/xem nội tuyến, đó là những gì đang xảy ra với ví dụ chức năng.

Các vấn đề liên quan