用于日期算术和比较的可移植SQL

时间:2011-02-15 20:39:30

标签: php sql datetime

SQL

用于存储用户会话的表:

CREATE TABLE sessions (
    user_id INT,
    expires TIMESTAMP
);

创建会话:

INSERT INTO sessions (user_id, expires) VALUES (:user_id,
    CURRENT_TIMESTAMP + INTERVAL '+15 minutes');

要检索会话:

SELECT * FROM sessions WHERE user_id = :user_id AND
    CURRENT_TIMESTAMP < expires;

问题

  • 这是便携式SQL吗? 这适用于通过PHP PDO extension(不包括SQLite)提供的任何数据库吗?

  • 这在不同的时区是否正确?跨夏令时调整?
    CURRENT_TIMESTAMP(包括时区信息)与TIMESTAMP列混合在一起时是否存在任何问题?(

3 个答案:

答案 0 :(得分:3)

根据我的经验,在SQL方言中,日期/时间值非常有问题。

  • Oracle支持DATETIMESTAMPTIMESTAMP WITH TIME ZONETIMESTAMP WITH LOCAL TIME ZONE
    • DB2支持DATE,TIME和TIMESTAMP。
    • SQL Server支持DATETIME和(最近)DATE。 SQL Server具有TIMESTAMP数据类型,但它不是您认为的那样。
    • MySQL支持DATE,DATETIME,TIMESTAMP,TIME和YEAR
    • PostgresSQL支持TIMESTAMP和TIME,包括和不包含时区,以及DATE

如果我必须以绝对可移植的方式处理日期/时间值,我会将该值存储为ISO8601紧凑形式的char / varchar

YYYYMMDDTHHMMSS[±HH:MM]

其中时间分量是24小时/军事时间。如果需要时区支持,请包括UTC的偏移量,或“Z”表示Zulu(UTC)时间。严格来说,如果没有'Z'后缀,ISO 8601日期/时间值应该被解释为当地时间。

根据您的需要,将日期和时间组件分成不同的列可能是值得的。

ISO8601为您提供

  • 可移植性
  • 正确的整理/比较
  • 易于解析

答案 1 :(得分:2)

虽然标准SQL,但有DBMS(例如SQL Server)不支持该标准。所以答案是肯定的,不是。

虽然我认为编写区间文字的ANSI标准方式是:INTERVAL '15' MINUTE,而不是你写的方式

答案 2 :(得分:1)

SQL Server不支持此功能。您必须使用dateadd函数。所以答案是不,这不是可移植的SQL。