Đó không phải là một lỗi, đó là một tính năng ... Có hai điểm ở đây.
-
Thay thế 'bây giờ'
Hãy xem tài liệu ( Ngày / Hàm và toán tử thời gian ):
Vì vậy,
'now'
được chuyển đổi thành dấu thời gian tại thời điểm phân tích cú pháp. -
Báo cáo soạn sẵn
Được rồi, nhưng nó có ý nghĩa gì đối với các chức năng? Thật dễ dàng để chứng minh rằng một hàm được thông dịch mỗi khi bạn gọi nó:
t=# create function test() returns timestamp as $$ begin return 'now'; end; $$ language plpgsql; CREATE FUNCTION t=# select test(); test ---------------------------- 2015-12-11 11:14:43.479809 (1 row) t=# select test(); test ---------------------------- 2015-12-11 11:14:47.350266 (1 row)
Trong ví dụ này
'now'
hoạt động như bạn mong đợi.Sự khác biệt là gì? Hàm của bạn sử dụng câu lệnh SQL, còn test () thì không. Hãy xem lại tài liệu ( PL / pgSQL Plan Caching ):
Và đây ( Chuẩn bị Tuyên bố ):
Do đó
'now'
đã được chuyển đổi thành dấu thời gian khi câu lệnh đã chuẩn bị được phân tích cú pháp. Hãy chứng minh điều này bằng cách tạo một câu lệnh chuẩn bị bên ngoài một hàm:t=# prepare s(integer) as UPDATE test_date_bug SET date2 = 'now' WHERE id = $1; PREPARE t=# execute s(1); UPDATE 1 t=# execute s(2); UPDATE 1 t=# select * from test_date_bug; id | date1 | date2 ----+-------------------------------+------------------------------- 3 | 2015-12-11 11:01:38.491656+03 | infinity 1 | 2015-12-11 11:01:37.91818+03 | 2015-12-11 11:40:44.339623+03 2 | 2015-12-11 11:01:37.931056+03 | 2015-12-11 11:40:44.339623+03 (3 rows)
Đó là những gì đã xảy ra. 'now'
đã được chuyển đổi thành dấu thời gian một lần (khi câu lệnh chuẩn bị được phân tích cú pháp) và now()
đã được gọi hai lần.