PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Công đoàn postgres có đảm bảo thứ tự thực hiện khi gọi các hàm có tác dụng phụ không?

Trên thực tế, chúng sẽ được thực hiện theo thứ tự đã cho, nhưng không có gì đảm bảo.

Nếu nó được đảm bảo, thì nó sẽ được đề cập trong tài liệu hoặc tiêu chuẩn SQL. Tôi không thấy bất kỳ đề cập nào về thứ tự thực hiện của một UNION trong một trong hai.

Nếu người tối ưu hóa có lý do để thực thi cái này trước cái kia thì nó sẽ được tự do làm như vậy.

Để đảm bảo thứ tự thực thi, hãy chạy các câu lệnh theo thứ tự mong muốn:

SELECT * FROM func1();
SELECT * FROM func2();

Nếu bạn muốn giảm các chuyến đi khứ hồi, hãy sử dụng các phương tiện phân lô của khách hàng nếu có thể, hoặc sử dụng DO khối:

DO
$$
BEGIN
  PERFORM proc1();
  PERFORM proc2();
END;
$$;

Nếu bạn cần trả về giá trị, hãy sử dụng một hàm và RETURN QUERY hoặc RETURN NEXT .

Hoặc bạn có thể buộc đặt hàng bằng CTE vì trong PostgreSQL (rất tiếc) CTE hoạt động như hàng rào tối ưu hóa buộc cụ thể hóa kết quả . Tuy nhiên, AFAIK PostgreSQL vẫn không phải thực thi các điều khoản CTE theo thứ tự chúng được viết hoặc thứ tự chúng được tham chiếu; đảm bảo duy nhất bạn nhận được là nếu bạn làm điều này:

WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;

rồi đến function1 phải được thực thi và hiện thực hóa trước. Đó là một sai lệch cụ thể của PostgreSQL mặc dù; nó không đúng với các công cụ cơ sở dữ liệu khác, không được đảm bảo bởi tiêu chuẩn và bạn không nên dựa vào nó.

Điều đó không mở rộng đến

WITH f1 AS (SELECT * FROM function1())
     f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;

... như trong trường hợp này PostgreSQL có thể thực thi các điều khoản CTE độc lập theo một trong hai thứ tự.

Một lần nữa, với các phép nối, nguyên tắc tương tự cũng được áp dụng. Nếu các điều khoản là độc lập thì hệ thống có thể chọn chạy chúng theo bất kỳ thứ tự nào, mặc dù nói chung là không. Vì vậy:

select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true

có thể đánh giá và hiện thực hóa bar() sau đó nối kết quả của nó trên foo() .

Nếu bạn muốn thực hiện theo thứ tự, bạn không nên dựa vào các hoạt động tập hợp như liên kết và liên kết. Sử dụng các truy vấn riêng biệt hoặc mã thủ tục.

Vâng, có.

SELECT * FROM function1();
SELECT * FROM function2();



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tham gia trên nhiều bảng bằng cách sử dụng

  2. gevent và posgres:Kết nối không đồng bộ không thành công

  3. Lưu trữ hình ảnh trong postgresql

  4. Xóa một bảng trong PostgreSQL mà không xóa một chuỗi được liên kết

  5. Spring JDBC - Id được chèn lần cuối