2017-03-07 66 views
1

我想在PostgreSQL中的函数中使用保存点功能。我读过这个保存点不能在Postgres的函数里面使用。PostgreSQL中的保存功能

但是,当我回滚,我想回滚到一个特定的点,因为我想使用保存点。什么是替代方法呢?

示例代码

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; 
+0

你需要'回滚到first_savepoint':https://www.postgresql.org/docs/current/static/sql-rollback-to.html –

+0

不能使用PostgreSQL的函数内的任何交易相关的SQL语句。 –

+0

回滚到first_savepoint不起作用,因为保存点不能在函数内部使用。我想知道替代保存点.. –

回答

2

在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相同,但后者通常被认为更具可读性。
+0

谢谢劳伦兹..代码是一个部分代码..所以它有一些未使用的东西,实际上在后面的部分使用。 –

+0

不,我不想返回0,我想回滚到一个特定的点(保存点作为保存点替代不能用于内部功能)..这是我发布这个问题的最重要原因.. –

+0

就像我写的,作为一旦进入'EXCEPTION'块,你就*回滚到保存点。 –