31

在文档中,我只能找到一种从字符串创建日期的方法,例如DATE '2000-01-02'. 这完全令人困惑和烦人。我想要的是一个接受三个参数的函数,所以我可以make_date(2000, 1, 2)使用整数而不是字符串,并返回一个日期(不是字符串)。PostgreSQL有这样的内置功能吗?

我问这个的原因是因为我不喜欢将字符串用于不是字符串的东西。日期不是字符串;他们是约会。

我使用的客户端库是用于 Haskell 的 HDBC-PostgreSQL。我正在使用 PostgreSQL 9.2.2。

4

4 回答 4

83

在 PostgreSQL 9.4 及更高版本中,实际上有一个make_date(year int, month int, day int)函数可以创建日期。

http://www.postgresql.org/docs/9.5/static/functions-datetime.html

于 2016-02-03T18:35:00.477 回答
18

通常需要在 SQL 中执行此操作通常表示您的数据模型存在问题,您将日期拆分为数据库中的字段而不是真实日期或时间戳字段,或者您有严重的转义和 SQL 注入问题。请参阅下面的说明。

以下任何一项都可以解决您的直接问题:

CREATE OR REPLACE FUNCTION make_date(year integer, month integer, day integer) AS $$
SELECT year * INTERVAL '1' YEAR + month * INTERVAL '1' MONTH + day * INTERVAL '1' DAY;
$$ LANGUAGE sql STRICT IMMUTABLE;

或者

CREATE OR REPLACE FUNCTION make_date(year integer, month integer, day integer) AS $$
SELECT format('%s-%s-%s', year, month, day)::date;
$$ LANGUAGE sql STRICT IMMUTABLE;

但请继续阅读。


你问这个的事实让我觉得你可能正在尝试在你的应用程序中构建 SQL,如下所示:

$sql = "SELECT date'" + year + '-' + month + '-' + day + "';";

这通常是危险错误的(尽管 if 可能不是直接不安全的yearmonth并且day是整数数据类型)。如果您这样做是为了避免SQL 注入并为自己省去很多转义和文字格式的麻烦,那么您应该使用参数化查询。请参阅http://bobby-tables.com/

以下是在 Python 中使用带有 psycopg2 的参数化语句查询日期的方法(因为您没有指定语言或工具):

import datetime
import psycopg2
conn = psycopg2.connect('')
curs = conn.cursor()
curs.execute('SELECT %s;', ( datetime.date(2000,10,05), ))
print repr(curs.fetchall());

这将打印:

[(datetime.date(2000, 10, 5),)]

即一个包含单个 Python 日期的数组。您可以看到它一直在通过数据库进行往返,而且您不必担心 PostgreSQL 的日期格式或表示,因为当您使用参数化语句时,psycopg2 和 PostgreSQL 会为您处理这些问题。请参阅此较早的相关答案

于 2013-03-10T01:45:52.573 回答
8

其他值得尝试的是to_date()功能。它类似于上面提到的绑定,不需要创建用户定义的函数。

http://www.postgresql.org/docs/current/static/functions-formatting.html

我以这种形式使用它:

to_Date(month::varchar ||' '|| year::varchar, 'mm YYYY')
于 2014-05-18T15:10:33.137 回答
0

你可以使用 date(concat())

select date(concat(2000::varchar, '-01-01'))
于 2022-02-01T14:13:20.767 回答