Різниця між now () та current_timestamp


45

У PostgreSQL я використовую функцію now()та current_timestampфункцію, і я не бачу різниці:

# SELECT now(), current_timestamp;
              now               |              now               
--------------------------------+--------------------------------
 04/20/2014 19:44:27.215557 EDT | 04/20/2014 19:44:27.215557 EDT
(1 row)

Я щось пропускаю?

Відповіді:


54

Різниці немає. Три цитати з посібника:

1)

Ці стандартні функції SQL усі повертають значення на основі часу початку поточної транзакції:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()еквівалентний CURRENT_TIMESTAMP, але призначений для чіткого відображення того, що він повертає.

3)

now()це традиційний еквівалент PostgreSQL transaction_timestamp().

Сміливий акцент мій. CURRENT_TIMESTAMP, transaction_timestamp()і now()зробіть точно так само. CURRENT_TIMESTAMPє синтаксичною диваком для функції, що не має кінцевих парних дужок. Це відповідно до стандарту SQL.

Якщо ви не оголошуєте псевдонім стовпця для виклику функції в операторі SQL, псевдонім за замовчуванням має назву функції. Внутрішньо, стандарт-SQL CURRENT_TIMESTAMPреалізований за допомогою now(). До Postgres 9.6, що відображається в отриманій назві стовпця , яка була "зараз", але змінена на "current_timestamp" у Postgres 10.

transaction_timestamp() робить те саме, але ця функція є належною функцією Postgres, тому псевдонім за замовчуванням завжди був "transak_timestamp".

Ви НЕ плутайте небудь з цих функцій зі спеціальною константою введення'now' . Це лише одна з декількох примітних скорочень для конкретних значень дати / часу / часової позначки, цитуючи посібник:

... що буде перетворено на звичайні значення дати / часу при прочитанні. (Зокрема, nowі пов'язані рядки перетворюються на певне значення часу, як тільки вони прочитаються.) Усі ці значення потрібно укласти в окремі лапки, коли вони використовуються як константи в SQL-командах.

Це може додати плутанини, що (принаймні до Постгресу 12) будь-яка кількість провідних і кінцевих пробілів і дужок ( {[( )]}) обрізана з цих спеціальних вхідних значень. Отож 'now()'::timestamptz- або 'now()'там, де не потрібен чіткий вигляд типів - також є дійсним і він має оцінюватися за тією ж міткою часу, що і функція now() в більшості контекстів . Але це константи і, як правило, не те, що потрібно, наприклад, за замовчуванням стовпця.

db <> fiddle тут
Стара SQL скрипка

Помітними альтернативами є statement_timestamp()і clock_timestamp(). Посібник:

statement_timestamp()повертає час початку поточного оператора (точніше, час отримання останнього повідомлення команди від клієнта). [...]
clock_timestamp()повертає фактичний поточний час, і тому його значення змінюється навіть у межах однієї команди SQL.

Примітка: statement_timestamp()це , STABLEяк зазначено вище (завжди повертає те ж значення в межах однієї і тієї ж команди SQL). Але clock_timestamp()обов'язково є тільки VOLATILE. Різниця може бути значною.


але чи має значення оптимізація запитів? тепер () буде виконуватися для кожного рядка в where items.createddate > now():?
santiago arizti

3
@santiagoarizti: Ні now()визначається STABLEтому, що воно оцінює однакове значення (час початку поточної транзакції) в межах однієї транзакції. Я, ваш приклад, now()виконується лише один раз (на відміну від, clock_timestamp()наприклад).
Ервін Брандстеттер

3

Крім того, що вони не мають функціональної різниці при правильному їх використанні, вони відкидаються по-різному:

'now()'відновлено (так само 'today'або 'now'):

b=# select 'now()'::timestamptz;
          timestamptz
-------------------------------
 2016-12-09 16:31:35.942243+00
(1 row)

'CURRENT_TIMESTAMP'дає смішні помилки з темних країв

Примітка: Поза PostgreSQL версії 7.2 "поточний" більше не підтримується як константа дати / часу

b=# select 'CURRENT_TIMESTAMP'::timestamptz;
ERROR:  date/time value "current" is no longer supported
LINE 1: select 'CURRENT_TIMESTAMP'::timestamptz;
               ^

і 'transaction_timestamp()'просто не реконфігурується як часова мітка зі значенням tz:

b=# select 'transaction_timestamp()'::timestamptz;
ERROR:  invalid input syntax for type timestamp with time zone: "transaction_timestamp()"
LINE 1: select 'transaction_timestamp()'::timestamptz;
               ^

Будь ласка, не запитуйте, чому б ви кинули 'now()' as timestamp. Я бачив where timestamp_column = 'now()'замість where timestamp_column = now()людей код, тому вважав, що це уточнення буде смішним фактом і гарним доповненням до відповіді Ервіна.


Це непорозуміння. Вхідна рядок'now()' виглядає аналогічно функції now()на поверхні, але не має прямого відношення інакше. 'now'є постійною оцінкою часу початку поточної транзакції . Трейлінг-парони ігноруються. Спроба кинути рядки 'CURRENT_TIMESTAMP'або 'transaction_timestamp()'до timestampподібним же чином виходить з ладу, тому що це просто маячня. Жодна з них не пов'язана з відповідними функціями.
Ервін Брандстеттер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.