PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Tabel partisi PostgreSQL yang mengelola sendiri

Anda mencampur double precision keluaran date_part() dengan text '-' . Itu tidak masuk akal untuk PostgreSQL. Anda akan membutuhkan pemeran eksplisit ke text . Tetapi ada cara yang lebih sederhana untuk melakukan semua ini:

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

Gunakan sebagai gantinya:

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

Ini juga tidak masuk akal:

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

Anda hanya dapat memberikan nilai dengan USING ayat. Baca manualnya di sini . Coba saja:

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

Atau lebih baik lagi, gunakan format format() . Lihat di bawah.

Juga, seperti @a_horse menjawab :Anda perlu menempatkan nilai teks Anda dalam tanda kutip tunggal.

Mirip di sini:

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

Sebagai gantinya:

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

Jawaban terkait:

Selain:Sementara "tanggal" diperbolehkan untuk nama kolom di PostgreSQL, ini adalah kata yang dicadangkan di setiap standar SQL . Jangan beri nama kolom Anda "tanggal", karena akan menyebabkan kesalahan sintaks yang membingungkan.

Demo kerja lengkap

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

Tes:

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. Bagaimana cara memeriksa apakah sel array tipe integer berisi nilai tertentu dalam SQL

  2. Memotong tampilan secara default di pernyataan pilih postgres psql

  3. Masukkan data ke Postgresql dengan nilai duplikat

  4. Hitung baris dalam partisi dengan Order By

  5. Temukan nama tabel yang direferensikan menggunakan tabel, bidang, dan nama skema