आप 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);