PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL:АКТУАЛИЗАЦИЯТА предполага преместване между дялове

Може да се накара да работи, тригерът, който извършва преместването, просто трябва да бъде дефиниран за всеки дял, а не за цялата таблица. Така че започнете, както направихте за дефинициите на таблици и тригера INSERT

CREATE TABLE records (
 record varchar(64) NOT NULL,
 active boolean default TRUE
);

CREATE TABLE active_records (CHECK (active)) INHERITS (records);
CREATE TABLE inactive_records (CHECK (NOT active)) INHERITS (records);

CREATE OR REPLACE FUNCTION record_insert()
RETURNS TRIGGER AS $$
BEGIN
  IF (TRUE = NEW.active) THEN
    INSERT INTO active_records VALUES (NEW.*);
  ELSE
    INSERT INTO inactive_records VALUES (NEW.*);
  END IF;
  RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER record_insert_trigger
 BEFORE INSERT ON records
 FOR EACH ROW EXECUTE PROCEDURE record_insert();

... нека имаме малко тестови данни ...

INSERT INTO records VALUES ('FirstLittlePiggy', TRUE);
INSERT INTO records VALUES ('SecondLittlePiggy', FALSE);
INSERT INTO records VALUES ('ThirdLittlePiggy', TRUE);
INSERT INTO records VALUES ('FourthLittlePiggy', FALSE);
INSERT INTO records VALUES ('FifthLittlePiggy', TRUE);

Сега тригерите на дяловете. Проверката if NEW.active =OLD.active се подразбира при проверката на стойността на active, тъй като знаем какво е позволено да бъде в таблицата на първо място.

CREATE OR REPLACE FUNCTION active_partition_constraint()
  RETURNS TRIGGER AS $$
    BEGIN
      IF NOT (NEW.active) THEN
        INSERT INTO inactive_records VALUES (NEW.*);
        DELETE FROM active_records WHERE record = NEW.record;
        RETURN NULL;
      ELSE
        RETURN NEW;
      END IF;
    END;
    $$
    LANGUAGE plpgsql;

CREATE TRIGGER active_constraint_trigger
  BEFORE UPDATE ON active_records
  FOR EACH ROW EXECUTE PROCEDURE active_partition_constraint();

CREATE OR REPLACE FUNCTION inactive_partition_constraint()
  RETURNS TRIGGER AS $$
    BEGIN
      IF (NEW.active) THEN
        INSERT INTO active_records VALUES (NEW.*);
        DELETE FROM inactive_records WHERE record = NEW.record;
        RETURN NULL;
      ELSE
        RETURN NEW;
      END IF;
    END;
    $$
    LANGUAGE plpgsql;

CREATE TRIGGER inactive_constraint_trigger
  BEFORE UPDATE ON inactive_records 
  FOR EACH ROW EXECUTE PROCEDURE inactive_partition_constraint();

... и тествайте резултатите ...

scratch=> SELECT * FROM active_records;
      record      | active 
------------------+--------
 FirstLittlePiggy | t
 ThirdLittlePiggy | t
 FifthLittlePiggy | t
(3 rows)

scratch=> UPDATE records SET active = FALSE WHERE record = 'ThirdLittlePiggy';
UPDATE 0
scratch=> SELECT * FROM active_records;
      record      | active 
------------------+--------
 FirstLittlePiggy | t
 FifthLittlePiggy | t
(2 rows)

scratch=> SELECT * FROM inactive_records;
      record       | active 
-------------------+--------
 SecondLittlePiggy | f
 FourthLittlePiggy | f
 ThirdLittlePiggy  | f
(3 rows)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. fe_sendauth:грешка без предоставена парола в postgresql + laravel

  2. Показване на резултати от клиентска заявка на PSQL 8.3+

  3. Как да намерите първото и последното срещане на конкретен знак в низ в PostgreSQL

  4. Как да се възползвате от новите функции за разделяне в PostgreSQL 11

  5. Затваряне на клиентска връзка на postgres (pg) в node.js