我有一个从php调用的postgres函数。函数的第一行在表中插入一些东西,将键返回到本地。
CREATE OR REPLACE FUNCTION uploadConfirm( bname text, ul text, pt text,
shp text, vzn integer,
gpsLoc double precision[], meta text ) RETURNS void AS $uC$
DECLARE
file Files%ROWTYPE;
shape text[];
locat_id integer;
crl_id integer;
uid integer DEFAULT(null);
iid integer;
make text;
model text;
BEGIN
insert into interact(webRequest) values(bname) RETURNING interact_id into iid;
shape := regexp_split_to_array( shp, E'x' ); -- get info for single file
--meta := encode( meta , 'base64' );
RAISE NOTICE 'uploadConfirm: % : % : % : % : % : % : %' , bname, ul, pt, shp , vzn, gpsLoc , meta ;
locat_id := getLocationId( gpsLoc[1],gpsLoc[2],gpsLoc[3] );
--RAISE 'meta: %d' , meta;
make := (regexp_matches( meta , $$Make\s+=\s+'([^']+)'$$ ))[1];
model := (regexp_matches( meta , $$Model\s+=\s+'([^']+)'$$ ))[1];
--RAISE '>> shape , loc_id, make, model: % : % : % : % ' , shape, loc_id, make, model ;
crl_id := getCurlId( '' , ul, pt, vzn );
select * into file from Files where Files.basename = bname;
IF NOT FOUND THEN
insert into Files
( basename , curl_id ) VALUES
( bname , crl_id ) returning * into file;
ELSE
update Files set ( curl_id ) =
( crl_id )
where basename = bname;
update interact set ( uid ) = ( file.uid ) where interact_id = iid;
END IF;
INSERT INTO Metadata VALUES ( meta , make , model , cast(shape[1] as integer), cast( shape[2] as integer) , file.file_id, locat_id );
EXCEPTION
WHEN not_null_violation THEN
perform reportError( 'File(bname='|| bname || ' no location data:' || SQLERRM, iid );
END;
$uC$ LANGUAGE plpgsql;
此函数有一个exception子句,它调用下面显示的错误报告函数。
CREATE OR REPLACE FUNCTION reportError( msgX text, iidX integer default(null) ) returns void as $re$
DECLARE
BEGIN
if iidX is null then
SELECT currval(pg_get_serial_sequence('interact', 'interact_id')) into iidX;
END IF;
insert into err (msg,iid) values ( msgX,iidX );
END;
$re$ LANGUAGE plpgsql;
调用另一个函数 reportError ,其中包含有关的信息(包括文件名, bname,和键, iid ,如上所示)表中的异常。
当我看时,虽然错误信息在表中应该是。 互动表中缺少具有相应键的条目。插入到交互中只能在bname为null时失败;但是,错误消息中存在bname(!= NULL)的值,因此我捕获的失败必须在代码中的后面按预期进行。
在我看来,互动的插入不应该回滚,但显然是。
我不明白为什么此条目不在互动表中。有人可以解释为什么&帮我弄清楚如何到达那里。
感谢。
答案 0 :(得分:0)
postgres docs说这究竟应该发生什么
When an error is caught by an EXCEPTION clause, the local variables
of the PL/pgSQL function remain as they were when the error occurred, but
all changes to persistent database state within the block are rolled back.
我应该对自己说RTM。
我可以在异常处理程序中重做我想要的插入。