Ошибка вставки в родительскую таблицу с новым столбцом

#sql #postgresql #partitioning

#sql #postgresql #разделение на разделы

Вопрос:

У меня есть основная таблица (оплата) и несколько секционированных таблиц (payment_AAAA_MM). Я получаю эти таблицы с помощью функции хранения, подобной этой:

 CREATE OR REPLACE FUNCTION partitioning_payment()
  RETURNS trigger AS
$BODY$
 DECLARE
 numero integer;
 month float;
 year float;
 monthp float;
 yearp float;
 months text;
 monthps text;
 
 BEGIN
 month=DATE_PART('month',NEW.REQUEST_TS);
 year=DATE_PART('year',NEW.REQUEST_TS);
 monthp=month;
 yearp=year;
 months=month;
 monthps=monthp;
 IF month = 12 THEN
 yearp=yearp 1;
 monthp=1;
 ELSE
 monthp=monthp 1;
 END IF;
 monthps=monthp;
 IF(length(month::text)=1) THEN
 months=month::text;
 months='0' || months;
 END IF;
 IF(length(monthp::text)=1) THEN
 monthps=monthp::text;
 monthps='0' || monthps;
 END IF;
 EXECUTE 'SELECT count(*) FROM PG_TABLES WHERE SCHEMANAME=''public'' AND TABLENAME=''payment_' || year || '_' || months || '''' INTO numero;
 IF numero=0 THEN
 EXECUTE 'CREATE TABLE payment_' || year || '_' || months || '(CHECK ( REQUEST_TS >= ''' || year || '-' || months || '-01 00:00:00'' and REQUEST_TS <  ''' || yearp || '-' || monthps || '-01 00:00:00'' )) inherits (payment)';
 END IF;
 
 EXECUTE 'INSERT INTO payment_' || year || '_' || months || ' (id,id_request,REQUEST_TS,response)
 VALUES (
 '''||NEW.ID||''',
 '''||NEW.ID_REQUEST||''',
 '''||NEW.REQUEST_TS||''',
 '''||NEW.RESPONSE||'''
 )';
 RETURN null; END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

CREATE TRIGGER partitioning_payment
  BEFORE INSERT
  ON payment
  FOR EACH ROW
  EXECUTE PROCEDURE partitioning_payment();
 

Все работает правильно.

Теперь мне нужно добавить в родительскую таблицу столбец (целочисленный тип is_test). Я добавил столбец в родительскую таблицу и изменил функцию таким образом

 CREATE OR REPLACE FUNCTION partitioning_payment()
  RETURNS trigger AS
$BODY$
 DECLARE
 numero integer;
 month float;
 year float;
 monthp float;
 yearp float;
 months text;
 monthps text;
 
 BEGIN
 month=DATE_PART('month',NEW.REQUEST_TS);
 year=DATE_PART('year',NEW.REQUEST_TS);
 monthp=month;
 yearp=year;
 months=month;
 monthps=monthp;
 IF month = 12 THEN
 yearp=yearp 1;
 monthp=1;
 ELSE
 monthp=monthp 1;
 END IF;
 monthps=monthp;
 IF(length(month::text)=1) THEN
 months=month::text;
 months='0' || months;
 END IF;
 IF(length(monthp::text)=1) THEN
 monthps=monthp::text;
 monthps='0' || monthps;
 END IF;
 EXECUTE 'SELECT count(*) FROM PG_TABLES WHERE SCHEMANAME=''public'' AND TABLENAME=''payment_' || year || '_' || months || '''' INTO numero;
 IF numero=0 THEN
 EXECUTE 'CREATE TABLE payment_' || year || '_' || months || '(CHECK ( REQUEST_TS >= ''' || year || '-' || months || '-01 00:00:00'' and REQUEST_TS <  ''' || yearp || '-' || monthps || '-01 00:00:00'' )) inherits (payment)';
 END IF;
 
 EXECUTE 'INSERT INTO payment_' || year || '_' || months || ' (id,id_request,REQUEST_TS,response,is_test)
 VALUES (
 '''||NEW.ID||''',
 '''||NEW.ID_REQUEST||''',
 '''||NEW.REQUEST_TS||''',
 '''||NEW.RESPONSE||''',
 '||NEW.IS_TEST||'
 )';
 RETURN null; END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
 

Однако теперь у меня такая ситуация:

  • В родительской таблице присутствует и секционированная таблица is_test
  • Если я сделаю вставку в секционированную таблицу, у меня будет новая строка
  • если я сделаю вставку в родительскую таблицу, ничего не произойдет

Итак, как я могу правильно добавить новый столбец и разрешить мне выполнить вставку в родительскую таблицу?

Комментарии:

1. Несвязанное, но «форматирование» months содержимого может быть упрощено до: months := to_char(NEW.REQUEST_TS, 'mm'); , т. Е. Вы можете извлечь это в форматированном виде непосредственно из значения даты (или метки времени), не копируя его туда и обратно между тремя переменными.

2. Я сделаю это позже, спасибо

Ответ №1:

Что ж… Как мне не стыдно. Я обновил процедуру, но вы должны удалить и воссоздать триггер в таблице платежей