1

Perl スクリプトでパラメーター化されたクエリを使用して、Postgres データベースからタイムスタンプを取得しようとしています。これは、教育目的のためだけに、切り詰めた例です。

私はタイムスタンプと間隔としてと を定義$start_dateしました:$end_date

my $start_date = "current_timestamp - interval '6 hours'";
my $end_date = "current_timestamp";

$dbh以下を使用して、以前に定義したデータベースに送信します。

my $sql = "SELECT cast(? as timestamp), cast(? as timestamp)";
my $sth = $dbh->prepare($sql);
$sth->execute($start_date, $end_date);

これを行うと、やや紛らわしいエラーが発生します。

DBD::Pg::st execute failed: ERROR:  date/time value "current" is no longer supported

current7.2 以降 PG でサポートされていないことは理解していますが、使用していません。サポートされているAFACTを使用してcurrent_timestampいます。つまり、私が入ると:psql

select (cast(current_timestamp - interval '6 hours' as timestamp), cast(current_timestamp as timestamp));

結果は私が期待するものです (2 つのタイムスタンプ、前者は後者の 6 時間前)。

now()の代わりに使用することもできますcurrent_timestamp。次の方法で使用できます。

my $start_date = "now() - interval '6 hours'"; 
my $end_date = "now()";

perl でクエリを実行しようとすると、次のエラーが発生します。

DBD::Pg::st execute failed: ERROR:  invalid input syntax for type timestamp: "now() - interval '6 hours'"

それでも、クエリ:

select (cast(now() - interval '6 hours' as timestamp), cast(now() as timestamp));

期待される結果が得られます。

私はかなり困惑しています。

4

2 に答える 2

5

問題は、SQL プレースホルダーが式ではなく単一の値を表すことです。そして、その値を関数にすることはできません。次のようなことができます:

my $start_date = "6 hours";
my $sql = "SELECT current_timestamp - cast(? as interval), current_timestamp";
my $sth = $dbh->prepare($sql);
$sth->execute($start_date);

Perl で行っていることは、これを で行うのと同じですpsql:

select (cast('current_timestamp - interval ''6 hours''' as timestamp), cast('current_timestamp' as timestamp));
于 2013-10-17T18:38:42.190 に答える
1

クエリのウィンドウをもう少し柔軟にするには:

$sth = $dbh->prepare(<<__eosql);
SELECT * FROM tbl
 WHERE ts BETWEEN current_timestamp - ? * CAST('1 ' || ? AS INTERVAL)
                  AND
                  current_timestamp;
__eosql

$sth->execute(6, 'hour');
$sth->execute(10, 'day');
$sth->execute(1, 'week');
# etc.

固定された時点を導入すると、パラメーターのデフォルトが現在の時間になる... WHERE COALESCE(?, current_timestamp) ...ことを覚えておくなど、あまりにも巧妙なことを行うことができます。undefただし、おそらく別のクエリを作成して準備するでしょう。

于 2013-10-17T20:55:38.217 に答える