Разница между 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)

Я что-то пропустил?

JohnMerlino
источник

Ответы:

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, который отображается в имени получающегося столбца , которое было «сейчас», но в Postgres 10 было изменено на «current_timestamp».

transaction_timestamp() делает то же самое, но эта функция является надлежащей функцией Postgres, поэтому псевдоним по умолчанию всегда был «action_timestamp ».

Вы не путайте либо из этих функций со специальной константой ввода'now' . Это всего лишь один из нескольких обозначений для конкретных значений даты / времени / метки времени, цитируя руководство:

... которые будут преобразованы в обычные значения даты / времени при чтении. (В частности, nowи связанные строки преобразуются в определенное значение времени, как только они прочитаны.) Все эти значения должны быть заключены в одинарные кавычки при использовании в качестве констант в командах SQL.

Это может добавить к путанице, что (по крайней мере до Postgres 12) любое количество начальных и конечных пробелов и скобок ( {[( )]}) обрезается от этих специальных входных значений. Таким образом 'now()'::timestamptz- или просто 'now()'там, где явное приведение типов не требуется - также допустимо и now() в большинстве случаев вычисляется с той же временной меткой, что и функция . Но это константы и, как правило, не те, которые вы хотите, например, по умолчанию для столбцов.

db <> скрипка здесь
Старая скрипка SQL

Известные альтернативы statement_timestamp()и clock_timestamp(). Руководство:

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

Примечание: statement_timestamp()это , STABLEкак указано выше (всегда возвращает то же значение в пределах одной и той же команды SQL). Но clock_timestamp()обязательно есть только VOLATILE. Разница может быть значительной.

Эрвин Брандштеттер
источник
но имеет ли это значение для оптимизации запросов? будет теперь () выполняться для каждой строки в where items.createddate > now():?
Сантьяго Аристи
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'дает забавную ошибку от темных краев

Примечание. Начиная с версии 7.2 PostgreSQL «current» больше не поддерживается как константа даты / времени.

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подобным же образом выходит из строя, потому что это просто бред. Ни то, ни другое не связано с соответствующими функциями.
Эрвин Брандштеттер