PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Bảng phân vùng PostgreSQL tự quản lý

Bạn đang trộn double precision đầu ra của date_part () với text '-' . Điều đó không có ý nghĩa với PostgreSQL. Bạn sẽ cần truyền rõ ràng thành text . Nhưng có một cách đơn giản hơn nhiều để thực hiện tất cả những điều này:

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

Sử dụng thay thế:

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

Điều này cũng không có ý nghĩa:

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

Bạn chỉ có thể cung cấp các giá trị bằng USING mệnh đề. Đọc hướng dẫn tại đây . Hãy thử thay thế:

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

Hoặc tốt hơn, hãy sử dụng định dạng format() . Xem bên dưới.

Ngoài ra, giống như @a_horse đã trả lời :Bạn cần đặt các giá trị văn bản của mình trong dấu ngoặc kép.

Tương tự ở đây:

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

Thay vào đó:

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

Câu trả lời liên quan:

Ngoài ra:Mặc dù "ngày" được cho phép đối với tên cột trong PostgreSQL, nó là từ dành riêng trong mọi tiêu chuẩn SQL . Không đặt tên cột của bạn là "ngày tháng", nó dẫn đến lỗi cú pháp khó hiểu.

Hoàn thành bản trình diễn làm việc

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

Kiểm tra:

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. Cách Round () hoạt động trong PostgreSQL

  2. Làm cách nào để cấp quyền cho người dùng trên tất cả các bảng mới trong Postgres?

  3. pg_dump với --exclude-table vẫn bao gồm các bảng đó trong các lệnh COPY nền mà nó chạy?

  4. Thiết lập sao chép Slony-I đơn giản.

  5. Tạo một hàm trong Postgresql không trả về giá trị tổng hợp