1

私はPostgres 8.3データベースで作業しており、PL/pgSQLを使用して、テーブルへの日付入力に基づいてテーブル名を生成する関数を作成しようとしていました:

たとえば、日付でインデックス付けされた一連のテーブルを作成する必要があります。

drop table one_day_11_13 cascade;
create table one_day_11_13 as
select * from master_table where
timestamp < '2012-11-14' and timestamp >= '2012-11-13';  

drop table one_day_11_14 cascade;
create table one_day_11_14 as
select * from master_table where
timestamp < '2012-11-15' and timestamp >= '2012-11-14';  

('11_13', '2012-11-14', '2012-11-13')これを行う方法は、たとえば上記の最初のテーブルを作成するための引数として取る PL/pgSQL 関数を作成することだと考えていました。適切な EXECUTE ステートメントをコーディングするのに問題があります。

この種のことを行う最善の方法は PL/pgSQL のやり過ぎですか?

4

1 に答える 1

4

まず、より新しいバージョンへのアップグレードを検討してください。8.3はもうすぐです。

8.3の場合、次のように機能します。

CREATE OR REPLACE FUNCTION f_recreate_tbl(date, date)
 RETURNS void AS
$func$
DECLARE
   -- derive tablename from first date
   _tbl text := 'one_day_' || to_char($1, 'MM_YY'); 
BEGIN

 -- Use IF EXISTS to avoid an exception when table does not exist.
EXECUTE
'DROP TABLE IF EXISTS ' || _tbl || ' CASCADE';

EXECUTE 
'CREATE TABLE ' || _tbl || ' AS
SELECT *
FROM   master_table
WHERE  timestamp >= ''' || $1::text || '''::date
AND    timestamp <  ''' || $2::text || '''::date';

END
$func$ LANGUAGE plpgsql;

電話:

SELECT f_recreate_tbl('2012-11-13'::date, '2012-11-14'::date);
  • 識別子をパラメータ化する場合は常に、純粋なSQLを使用することはできません。EXECUTEPL / pgSQL関数またはDO(バージョン9.0以降)で動的SQLを使用します。

  • このバージョンは十分に安全です。より柔軟な入力を使用すると、 SQLインジェクションの可能性を回避するためにquote_ident()quote_literal()識別子と値をサニタイズする必要があります。

  • 最新バージョン(8.4以降)では、このUSING句を使用して、パラメーターのテキストへのキャストをスキップします。

  • timestamp列名として使用しないでください。これはデータ型の名前です。

  • を使用しDROP TABLE IF EXISTSます。8.3ですでに利用可能です。

  • 日付からテーブル名を取得し、3番目のパラメーターをスキップします。単純化のように見えた。

于 2012-12-10T19:39:42.940 に答える