B
B
Bogdan2017-08-14 17:00:47
PostgreSQL
Bogdan, 2017-08-14 17:00:47

Document number in the context of the department?

Hello. Here I gave birth to my first first trigger function. Which generates a document number. Can you recommend something sensible in terms of refractoring?

-- Функция генерации номера документа в разрезе подразделения и префикса у автоинкриментым увеличением
CREATE OR REPLACE FUNCTION doc_number() RETURNS trigger AS $$
  DECLARE 
        _prefix varchar;
  _number_prev varchar;
  	_index_cur integer := 1;
  	_number_cur varchar;
  	_lenght_number integer;
  BEGIN
    -- Префикс с таблицы подразделений
    _prefix = ( SELECT trim(aa.prefix) FROM institutions aa WHERE aa.id = NEW.institution_id ) || '-' ; 
    -- Размер поля что бы сформировать правильное количество итоговых символов
    _lenght_number = ( SELECT aa.character_maximum_length FROM INFORMATION_SCHEMA.COLUMNS aa 
                       WHERE aa.table_name = TG_TABLE_NAME AND column_name = 'number' );
    -- Последнее (максимальное) значения по подразделению и префиксе (префикс могут поменять, а потом вернуть обратно)	                     
  EXECUTE format( 'SELECT MAX(aa.number) FROM %s aa WHERE aa.institution_id = %s AND aa.number ~ %L', 
                  TG_TABLE_NAME, NEW.institution_id, _prefix ) INTO _number_prev;
  -- Если найдено значенние
 	IF _number_prev IS NOT NULL then
 		-- Вырезаем из подстроки регулярным выражение цифровой номер и + 1
 	  _index_cur = ( regexp_matches( _number_prev, '-([0-9]*)$' ) )[ 1 ]::integer + 1;
 	END IF;
  -- Отформатированный префиксом и ледирующими нулzvb номер размером на все поле, пример "KL-000000060"
    NEW.number := _prefix || to_char( _index_cur, 'FM' || repeat('0', _lenght_number - length( _prefix ) ) );
    RETURN NEW;
  END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS institution_order_number ON institution_orders; 

-- Триггер срабатывает только при наличии подразделения и отсуствии номера документа
CREATE TRIGGER institution_order_number 
  BEFORE INSERT ON institution_orders
    FOR EACH ROW
      WHEN ( NEW.institution_id IS NOT NULL AND NEW.number IS NULL )
    EXECUTE PROCEDURE doc_number();

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question