我想在 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
块。在底层,这会在 BEGIN
设置一个保存点,并在遇到异常时回滚到该保存点。
所以你的代码可能看起来像这样(我不确定我是否正确阅读了你的代码):
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
相同,但后者通常被认为更具可读性。另一个答案中的代码在 PostgreSQL 15 中对我不起作用,但这是有效的(我在那里添加了引发异常):
create or replace function wurst() returns setof companytaxtype as $$
declare
x companytaxtype; begin
-- Begin savepoint
BEGIN
-- Change environment for following query
update companytaxtype set name = 'Ausland' where name = 'Inland';
-- Query data in changed environment
for x in
select * from companytaxtype
loop
return next x;
end loop;
-- Rollback savepoint
raise exception 'some name';
EXCEPTION
WHEN OTHERS THEN RETURN;
END;
end $$ language plpgsql;