PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Samozarządzające tablice partycji PostgreSQL

Mieszasz double precision wyjście date_part() z text '-' . To nie ma sensu dla PostgreSQL. Potrzebujesz wyraźnego rzutowania na text . Ale jest o wiele prostszy sposób na zrobienie tego wszystkiego:

startdate:=date_part('year',to_timestamp(NEW.date))
||'-'||date_part('month',to_timestamp(NEW.date))
||'-'||date_part('day',to_timestamp(NEW.date));

Użyj zamiast:

startdate := to_char(NEW.date, 'YYYY-MM-DD');

To też nie ma sensu:

EXECUTE 'CREATE TABLE $1 (
        CHECK (date >= DATE $2 AND date < DATE $3 )
    ) INHERITS (pings)' USING quote_ident(tablename),startdate,enddate;

Możesz podać tylko wartości z USING klauzula. Przeczytaj instrukcję tutaj . Spróbuj zamiast tego:

EXECUTE 'CREATE TABLE ' || quote_ident(tablename) || ' (
            CHECK ("date" >= ''' || startdate || ''' AND
                   "date" <  ''' || enddate   || '''))
            INHERITS (ping)';

Lub jeszcze lepiej, użyj formatu format() . Zobacz poniżej.

Podobnie jak @a_horse odpowiedział :Musisz umieścić swoje wartości tekstowe w pojedynczych cudzysłowach.

Podobne tutaj:

EXECUTE 'INSERT INTO $1 VALUES (NEW.*)' USING quote_ident(tablename);

Zamiast tego:

EXECUTE 'INSERT INTO ' || quote_ident(tablename) || ' VALUES ($1.*)'
USING NEW;

Powiązana odpowiedź:

Na marginesie:Chociaż „data” jest dozwolona dla nazwy kolumny w PostgreSQL, jest to zarezerwowane słowo w każdym standardzie SQL . Nie nazywaj swojej kolumny „datą”, prowadzi to do mylących błędów składniowych.

Pełne działające demo

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

Testy:

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

Skrzypce SQL.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wiele-do-wielu w sqlalchemii. Zapobieganie wstawianiu SQLAlchemy do tabeli, jeśli tag już istnieje

  2. Jak zaimportować moduły lub zainstalować rozszerzenia w PostgreSQL 9.1+?

  3. Generowanie uporządkowanej rangi sekwencji na złożonym zapytaniu

  4. Dodaj ograniczenie, aby kolumna była unikalna dla grupy wierszy

  5. Dlaczego nie można przekonwertować wartości NULL na wartość JSON w postgreSQL?