ความแตกต่างระหว่าง 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 ที่เหมาะสมดังนั้นนามแฝงเริ่มต้นจะเป็น "transaction_timestamp" เสมอ

อย่าได้สร้างความสับสนให้ทั้งของทั้งฟังก์ชั่นที่มีความพิเศษอย่างต่อเนื่องการป้อนข้อมูล 'now'นั่นเป็นเพียงหนึ่งในสัญลักษณ์ย่อที่หลากหลายสำหรับค่าวันที่ / เวลา / เวลาประทับที่ระบุโดยอ้างถึงคู่มือ:

... ที่จะถูกแปลงเป็นค่าวันที่ / เวลาสามัญเมื่ออ่าน (โดยเฉพาะอย่างยิ่งnowและสตริงที่เกี่ยวข้องจะถูกแปลงเป็นค่าเวลาที่ระบุทันทีที่อ่าน) ค่าทั้งหมดเหล่านี้ต้องอยู่ในเครื่องหมายคำพูดเดี่ยวเมื่อใช้เป็นค่าคงที่ในคำสั่ง SQL

มันอาจเพิ่มความสับสนที่ (อย่างน้อยที่สุด Postgres 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()ตัวอย่าง)
Erwin Brandstetter

3

นอกจากนี้พวกเขาไม่มีความแตกต่างในการใช้งานเมื่อคุณใช้อย่างถูกต้อง

'now()'recongnized (เหมือน'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'เป็นค่าคงที่ประเมินกับเวลาเริ่มต้นการทำธุรกรรมปัจจุบัน parens ต่อท้ายจะถูกละเว้น ความพยายามที่จะโยนสตริง'CURRENT_TIMESTAMP'หรือ'transaction_timestamp()'ไปtimestampในลักษณะคล้ายล้มเหลวเนื่องจากว่าเป็นเรื่องไร้สาระเพียง ไม่เกี่ยวข้องกับฟังก์ชั่นที่เกี่ยวข้อง
Erwin Brandstetter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.