2015-03-22 2 views
0

У меня есть функция postgres, называемая php. Первая строка функции вставляет что-то в таблицу, возвращая ключ в локальный.insert rollback after catch exception 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; 

Эта функция имеет предложение исключения, которое вызывает функцию сообщения об ошибках, показанную ниже.

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

Вам нужно будет показать полную функцию или, по крайней мере, соответствующий блок, а также определение 'reportError'. –

ответ

0

Postgres документы говорят это exaclty, что должно произойти

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, к себе.

Я могу переделать вставку, которую я хочу в обработчике исключений.