PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL विभाजन तालिका का स्व-प्रबंधन

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

परीक्षण:

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

SQL Fiddle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या PostgreSQL में प्राथमिक कुंजी के रूप में UUID खराब सूचकांक प्रदर्शन देगा?

  2. क्यों pg_restore सफलतापूर्वक लौट रहा है लेकिन वास्तव में मेरे डेटाबेस को पुनर्स्थापित नहीं कर रहा है?

  3. पोस्टग्रेज:यदि यह पहले से मौजूद नहीं है तो बाधा जोड़ें

  4. Psycopg2 में SQL के लिए मापदंडों की सूची पास करना

  5. ऐसी स्थिति जहां ActiveRecord और SQL अज्ञात OID को स्ट्रिंग के रूप में माने जाने के कारण समान परिणाम नहीं लौटाते हैं