Perbedaan antara now () dan current_timestamp

45

Dalam PostgreSQL, saya menggunakan now()dan current_timestampfungsi dan saya tidak melihat perbedaan:

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

Apakah saya melewatkan sesuatu?

JohnMerlino
sumber

Jawaban:

54

Tidak ada perbedaan. Tiga kutipan dari manual:

1)

Fungsi standar SQL ini semua nilai pengembalian berdasarkan waktu mulai dari transaksi saat ini:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()setara dengan CURRENT_TIMESTAMP, tetapi dinamai dengan jelas mencerminkan apa yang dikembalikan.

3)

now()adalah setara dengan PostgreSQL tradisional transaction_timestamp().

Penekanan berani saya. CURRENT_TIMESTAMP, transaction_timestamp()dan now()lakukan hal yang persis sama. CURRENT_TIMESTAMPadalah keanehan sintaksis untuk suatu fungsi, tidak memiliki pasangan tanda kurung. Itu sesuai dengan standar SQL.

Jika Anda tidak mendeklarasikan alias kolom untuk panggilan fungsi dalam pernyataan SQL, alias default ke nama fungsi. Secara internal, standar-SQL CURRENT_TIMESTAMPdiimplementasikan dengan now(). Hingga Postgres 9.6 yang menunjukkan nama kolom yang dihasilkan , yang "sekarang", tetapi diubah menjadi "current_timestamp" di Postgres 10.

transaction_timestamp() melakukan hal yang sama, tetapi yang ini adalah fungsi Postgres yang tepat, jadi alias default selalu menjadi "transaction_timestamp".

Jangan tidak membingungkan salah satu dari ini fungsi dengan khusus masukan konstan'now' . Itu hanya salah satu dari beberapa singkatan notasi untuk nilai tanggal / waktu / cap waktu tertentu, mengutip manual:

... yang akan dikonversi menjadi nilai tanggal / waktu biasa saat dibaca. (Secara khusus, nowdan string terkait dikonversi ke nilai waktu tertentu segera setelah dibaca). Semua nilai ini perlu dimasukkan dalam tanda kutip tunggal ketika digunakan sebagai konstanta dalam perintah SQL.

Ini dapat menambah kebingungan bahwa (hingga setidaknya Postgres 12) sejumlah spasi dan tanda kurung terkemuka ( {[( )]}) dipangkas dari nilai input khusus tersebut. Jadi 'now()'::timestamptz- atau hanya di 'now()'mana tidak ada pemeran tipe eksplisit diperlukan - juga valid dan terjadi untuk mengevaluasi stempel waktu yang sama dengan fungsi now() dalam sebagian besar konteks . Tapi itu adalah konstanta dan biasanya bukan yang Anda inginkan sebagai default kolom misalnya.

db <> biola di sini
Old biola SQL

Alternatif penting adalah statement_timestamp()dan clock_timestamp(). Manual:

statement_timestamp()mengembalikan waktu mulai dari pernyataan saat ini (lebih khusus, waktu penerimaan pesan perintah terbaru dari klien). [...]
clock_timestamp()mengembalikan waktu aktual saat ini, dan karenanya nilainya berubah bahkan dalam satu perintah SQL.

Catatan: statement_timestamp()adalah STABLEseperti di atas (selalu mengembalikan nilai yang sama dalam perintah SQL yang sama). Tetapi clock_timestamp()tentu saja VOLATILE. Perbedaannya mungkin signifikan.

Erwin Brandstetter
sumber
tetapi, apakah itu membuat perbedaan untuk optimasi kueri? akan sekarang () akan dieksekusi untuk setiap baris dalam: where items.createddate > now()?
santiago arizti
3
@santiagoarizti: No. now()didefinisikan STABLEkarena mengevaluasi ke nilai yang sama (waktu mulai dari transaksi saat ini) dalam transaksi yang sama. Saya contoh Anda, now()dieksekusi hanya sekali (sebagai lawan clock_timestamp()misalnya).
Erwin Brandstetter
3

Selain itu, mereka tidak memiliki perbedaan fungsional ketika Anda menggunakannya dengan benar, mereka dicetak secara berbeda:

'now()'recongnized (seperti 'today'atau 'now'):

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

'CURRENT_TIMESTAMP'memberikan kesalahan lucu dari tepi yang gelap

Catatan: Pada PostgreSQL versi 7.2, 'saat ini' tidak lagi didukung sebagai konstanta tanggal / waktu

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

dan 'transaction_timestamp()'tidak hanya rekam sebagai cap waktu dengan nilai tz:

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

Tolong jangan tanya mengapa Anda memilih 'now()' as timestamp. Saya telah melihat where timestamp_column = 'now()'alih - alih where timestamp_column = now()dalam kode orang, jadi pikir klarifikasi ini akan menjadi fakta lucu dan tambahan yang bagus untuk jawaban Erwin.

Vao Tsun
sumber
Ini adalah kesalahpahaman. The string input'now()' terlihat mirip dengan fungsi now()di permukaan, tetapi tidak secara langsung berhubungan sebaliknya. 'now'adalah evaluasi konstan terhadap waktu mulai transaksi saat ini . Trailing parens diabaikan. Upaya untuk melemparkan string 'CURRENT_TIMESTAMP'atau 'transaction_timestamp()'dengan timestampcara yang sama gagal, karena itu hanya omong kosong. Tidak ada yang terkait dengan fungsi yang sesuai.
Erwin Brandstetter