一尘不染

是否存在需要花费一年,几个月和一天才能在PostgreSQL中创建日期的函数?

sql

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

我之所以这样问,是因为我不喜欢将字符串用于不是字符串的东西。日期不是字符串;他们是约会。

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


阅读 147

收藏
2021-05-16

共1个答案

一尘不染

通常需要在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和均为整数数据类型year,可能并非直接不安全)。如果这样做是为了避免SQL注入并通过转义和文字格式设置为自己节省很多麻烦,那么应该使用
参数化查询 。参见http://bobby-tables.com/month``day
__

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

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会为您解决这一问题。

2021-05-16