Точка сохранения в функции PostgreSql

Я хочу использовать функцию точки сохранения внутри функции в PostgreSQL. Я читал, что точки сохранения нельзя использовать внутри функций в Postgres.

Но пока я откатываюсь, я хочу откатиться на конкретную точку, из-за которой хочу использовать точку сохранения. Каков альтернативный способ сделать это?

Образец кода

CREATE or replace FUNCTION fn_loadData_Subha()
RETURNS BIGINT 
AS 
$$
DECLARE
    batchId BIGINT;   
    currentTime TIMESTAMP;
    processName VARCHAR(20);
BEGIN


-- Getting current date and time
select TIMESTAMP 'NOW' into currentTime;
select 'ETL_Subha' INTO processName;

SAVEPOINT first_savepoint;
-- Inserting new record into batch log table
INSERT INTO TB_HSS_BATCH_LOG
(PROCESS_NAME,START_DATE,STATUS)
SELECT processName,currentTime,'STARTED';

select currval('TB_HSS_BATCH_LOG_id_seq') INTO batchId;

-- Inserting cost data to history table
    Insert into tb_hss_procedure_cost_hist1
    (HOSP_SYSTEM, HOSP_FACILITY, surgeon_name, procedure_name, department, current_dept_rank, no_of_surgeons, current_imp_cost
     , current_med_surg_cost, current_total_cost, annual_volume, sys_pref_cost,load_seq_no, CREATED_AT)
    Select  
    HOSP_SYSTEM, HOSP_FACILITY,surgeon_name,procedure_name,department,current_dept_rank, no_of_surgeons, current_imp_cost
    , current_med_surg_cost, current_total_cost, annual_volume, sys_pref_cost, batchId,currentTime
    from tb_hss_procedure_cost_stag_in; 

RELEASE SAVEPOINT first_savepoint;    
RETURN 1;


EXCEPTION
WHEN PLPGSQL_ERROR THEN 
  RAISE EXCEPTION '% %', SQLERRM, SQLSTATE; 
  RAISE NOTICE '% %', SQLERRM, SQLSTATE; 
  RETURN 0;
WHEN OTHERS THEN
  RAISE EXCEPTION '% %', SQLERRM, SQLSTATE; 
  RAISE NOTICE '% %', SQLERRM, SQLSTATE; 
  RETURN 0;
  ROLLBACK TRANSACTION;

END;
$$LANGUAGE plpgsql;

person Subhasree Mitra    schedule 07.03.2017    source источник
comment
Вам нужно rollback to first_savepoint: postgresql.org/docs/current/static/ sql-rollback-to.html   -  person a_horse_with_no_name    schedule 07.03.2017
comment
Вы не можете использовать какие-либо операторы SQL, связанные с транзакциями, внутри функции PostgreSQL.   -  person Laurenz Albe    schedule 07.03.2017
comment
откат к first_savepoint не работает внутри функции, так как внутри функции нельзя использовать точку сохранения. Я хочу знать альтернативу точки сохранения ..   -  person Subhasree Mitra    schedule 07.03.2017


Ответы (1)


Способ использования точек сохранения в функциях PL/pgSQL заключается в использовании блока BEGIN ... EXCEPTION ... END. Под капотом это устанавливает точку сохранения на BEGIN и откатывается к ней при возникновении исключения.

Таким образом, ваш код может выглядеть так (я не уверен на 100%, правильно ли я прочитал ваш код):

DECLARE
   batchid bigint;
   processname varchar(20) := 'ETL_Subha';
BEGIN
   BEGIN
      INSERT INTO TB_HSS_BATCH_LOG
         (PROCESS_NAME,START_DATE,STATUS)
         VALUES (processname,current_timestamp,'STARTED')
         RETURNING id INTO batchid;
      RETURN 1;
   EXCEPTION
      WHEN OTHERS THEN
         RETURN 0;
   END;
END;

Некоторые общие замечания к вашему коду:

  • batchid никогда не используется.
  • currenttime не требуется, каждый вызов current_time будет возвращать одно и то же значение в транзакции.
  • Вызов исключения с помощью RAISE остановит выполнение. Если вы хотите, чтобы возникла ошибка, просто не перехватывайте исходное исключение; это будет более значимо, чем ваше исключение. Мой код выше предполагает, что вы хотите поймать исключение и вместо этого хотите вернуть 0.
  • SELECT val INTO variable внутри то же самое, что и variable := value, но последний обычно считается более читабельным.
person Laurenz Albe    schedule 07.03.2017
comment
Спасибо Laurenz. Код является частичным кодом... поэтому в нем есть некоторые неиспользуемые материалы, которые фактически используются в более поздней части. - person Subhasree Mitra; 07.03.2017
comment
Нет, я не хочу возвращать 0, я хочу вернуться к определенной точке (альтернатива точке сохранения, поскольку точка сохранения не может использоваться внутри функции).. это самая важная причина, по которой я разместил этот вопрос. - person Subhasree Mitra; 07.03.2017
comment
Как я уже писал, как только вы входите в блок EXCEPTION, вы откатываетесь к точке сохранения. - person Laurenz Albe; 07.03.2017
comment
Я не мог ввести точку сохранения в функцию, так как это было запрещено. - person Subhasree Mitra; 08.03.2017
comment
Я сказал: Способ использования точек сохранения в функциях PL/pgSQL заключается в использовании блока BEGIN ... EXCEPTION ... END. Под капотом это устанавливает точку сохранения в BEGIN и откатывается к ней при возникновении исключения. Таким образом, вы уже ввели точку сохранения, если пишете такой блок. - person Laurenz Albe; 08.03.2017