web-dev-qa-db-ja.com

PostgreSQLで日付を作成するのに年、月、日かかる関数はありますか?

ドキュメントでは、文字列から日付を作成する方法しか見つかりませんでした。 _DATE '2000-01-02'_。これは完全に混乱し、迷惑です。代わりに必要なのは、3つのパラメーターを受け取る関数なので、make_date(2000, 1, 2)を実行して、文字列の代わりに整数を使用し、(文字列ではなく)日付を返すことができます。 PostgreSQLにはそのような組み込み関数がありますか?

私がこれを求めている理由は、文字列ではないものに文字列を使用するのが嫌いなためです。日付は文字列ではありません。彼らは日付です。

私が使用しているクライアントライブラリはHDBC-PostgreSQLforHaskellです。 PostgreSQL9.2.2を使用しています。

20
user142019

通常、SQLでこれを行う必要があるということは、実際の日付またはタイムスタンプフィールドとしてではなく、DB内のフィールドに分割された日付を格納しているデータモデルに問題があるか、深刻なエスケープと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 + "';";

これは一般的に危険および間違っています(おそらく直接危険ではありませんがyearmonthおよびdayは整数データ型です)。これが回避するために行っていることである場合は、代わりにパラメーター化されたクエリを使用する必要があります SQLインジェクション そして多くの手間を省きますエスケープとリテラルフォーマットを使用します。 http://bobby-tables.com/ を参照してください。

Python with 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日付を含む配列。データベースを往復しており、psycopg2以降、PostgreSQLの日付形式や表現について心配する必要がないことがわかります。パラメータ化されたステートメントを使用する場合は、PostgreSQLがそれを処理します。 この以前の関連する回答 を参照してください。

9
Craig Ringer

PostgreSQL 9.4以降には、実際には日付を作成するmake_date(year int, month int, day int)関数があります。

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

38
Gregory Arenius

他に試す価値のあるものは、to_date()関数です。これは上記のバインディングに似ており、ユーザー定義関数を作成する必要はありません。

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

私はそれをこの形で使用します:

to_Date(month::varchar ||' '|| year::varchar, 'mm YYYY')
5
user2027647