double precision
を混合しています date_part()
の出力 text '-'
。それはPostgreSQLには意味がありません。 text
への明示的なキャストが必要になります 。しかし、これをすべて行うにはもっと簡単な方法があります:
startdate:=date_part('year',to_timestamp(NEW.date))
||'-'||date_part('month',to_timestamp(NEW.date))
||'-'||date_part('day',to_timestamp(NEW.date));
代わりに使用してください:
startdate := to_char(NEW.date, 'YYYY-MM-DD');
これも意味がありません:
EXECUTE 'CREATE TABLE $1 (
CHECK (date >= DATE $2 AND date < DATE $3 )
) INHERITS (pings)' USING quote_ident(tablename),startdate,enddate;
USING
でのみ値を指定できます 句。 こちらのマニュアルをお読みください> 。代わりに試してください:
EXECUTE 'CREATE TABLE ' || quote_ident(tablename) || ' (
CHECK ("date" >= ''' || startdate || ''' AND
"date" < ''' || enddate || '''))
INHERITS (ping)';
または、format()
。以下を参照してください。
また、@a_horse回答 のように :テキスト値は一重引用符で囲む必要があります。
ここに似ています:
EXECUTE 'INSERT INTO $1 VALUES (NEW.*)' USING quote_ident(tablename);
代わりに:
EXECUTE 'INSERT INTO ' || quote_ident(tablename) || ' VALUES ($1.*)'
USING NEW;
関連する回答:
余談ですが、PostgreSQLでは列名に「日付」が許可されていますが、これはすべてのSQL標準で予約語 。列に「日付」という名前を付けないでください。混乱を招く構文エラーが発生します。
完全な作業デモ
CREATE TABLE ping (ping_id integer, the_date date);
CREATE OR REPLACE FUNCTION trg_ping_partition()
RETURNS trigger AS
$func$
DECLARE
_tbl text := to_char(NEW.the_date, '"ping_"YYYY_DDD_') || NEW.ping_id;
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' -- your schema
AND c.relname = _tbl
AND c.relkind = 'r') THEN
EXECUTE format('CREATE TABLE %I (CHECK (the_date >= %L AND
the_date < %L)) INHERITS (ping)'
, _tbl
, to_char(NEW.the_date, 'YYYY-MM-DD')
, to_char(NEW.the_date + 1, 'YYYY-MM-DD')
);
END IF;
EXECUTE 'INSERT INTO ' || quote_ident(_tbl) || ' VALUES ($1.*)'
USING NEW;
RETURN NULL;
END
$func$ LANGUAGE plpgsql SET search_path = public;
CREATE TRIGGER insbef
BEFORE INSERT ON ping
FOR EACH ROW EXECUTE PROCEDURE trg_ping_partition();
-
更新: Postgresの新しいバージョンには、テーブルが存在するかどうかを確認するためのより洗練された方法があります。
-
to_char()
date
を取ることができます$1
として 。これはtimestamp
に変換されます 自動的に。日付/時刻機能に関するマニュアル 。 -
(オプション)
SET
search_path
変更されたsearch_path
による不正行為を回避するための関数のスコープ 設定。 -
他の複数の簡素化と改善。コードを比較してください。
テスト:
INSERT INTO ping VALUES (1, now()::date);
INSERT INTO ping VALUES (2, now()::date);
INSERT INTO ping VALUES (2, now()::date + 1);
INSERT INTO ping VALUES (2, now()::date + 1);