postgresql - PostgreSql 函数中的保存点

标签 postgresql plpgsql savepoints

我想在 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;

最佳答案

在 PL/pgSQL 函数中使用保存点的方法是使用 BEGIN ... EXCEPTION ... END block 。在引擎盖下,这在 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 引发异常将终止执行。如果你想抛出一个错误,就不要捕获原来的异常;它会比你的异常(exception)更有意义。我上面的代码假定您想要捕获异常并返回 0。
  • SELECT val INTO variable 在底层与 variable := value 相同,但通常认为后者更具可读性。

关于postgresql - PostgreSql 函数中的保存点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42638907/

相关文章:

java - Hibernate中如何进行保存点和回滚?

python - Django 将对象从一个数据库移动到另一个数据库

javascript - 如何更新sequelize.query 中的多个列

python - 文件未找到错误: [Errno 2] No such file or directory: '/var/lib/pgadmin/azurecredentialcache'

mysql - 如何将巨大的 MySQL 数据库迁移到 PostgreSQL 数据库

postgresql - 当声明出现语法错误时 declare postgresql

database - 从 PostgreSQL 函数生成 HTML

sql - 如何从 PL/pgSQL 触发器函数中的变量派生 UPDATE 中的列名?

sql-server - 在存储过程中使用 SAVE TRANSACTION SavePointName