Ошибка в процедуре Помогите плиз !!

Дмитрий Голубев
Дата: 10.11.2004 11:36:21
Привет всем

Сорри туплю наверно, но просто не понимаю.
Подскажите пожалуста в чем проблема ?

CREATE OR REPLACE FUNCTION prc_test_t( 
	int4, int4
) RETURNS int4 AS '
DECLARE
	vP_UID ALIAS FOR $1;
	vP_MethodID ALIAS FOR $2;
	vRowExists int4;
BEGIN 
	BEGIN WORK ;

	SELECT COUNT(*) INTO vRowExists FROM test WHERE UID = vP_UID;

	IF ( vRowExists > 0 ) THEN 
		UPDATE 
			test 
		SET
			MethodID = vP_MethodID
		WHERE 
			UID = vP_UID;
	ELSE 
		INSERT INTO test ( MethodID ) VALUES ( vP_MethodID );
	END IF;

	COMMIT WORK;

	RETURN  0;
END;
' LANGUAGE 'plpgsql' ;

при выполнении "select * from prc_test_t( 0, 1 )"
ругается
ERROR: syntax error at or near ""
CONTEXT: compile of PL/pgSQL function "prc_test_t" near line 30

Объясните пожалуста в чем проблема
Спасибо
фффф
Дата: 11.11.2004 03:30:18
Транзакцию в функции нельзя начинать.
Дмитрий Голубев
Дата: 11.11.2004 12:08:01
Плохо, мягко выражаясь.

Можноли какимто образом выполнить несколько запросов и в случае ошибки хотябы в одном откатить все ??

тоесть типа
BEGIN TRANSACTION

insert_1
IF ERROR THEN ROLLBACK ; RETURN -1;

insert_2
IF ERROR THEN ROLLBACK ; RETURN -1;

update_X
IF ERROR THEN ROLLBACK ; RETURN -1;

COMMIT TRANSACTION

Помогите пожалуста.
Везде написано Постгре поддерживает транзакции, но нигде не написано как с ними работать.

Спасибо и извините за возможно глупые вопросы.
фффф
Дата: 11.11.2004 12:26:20
Про работу с транзакциями написано (сюрприз!) в официальной документации.
Функция всегда выполняется в транзакции, хочешь этого или нет. То, что ты описал - в функции работает по-умолчанию. Как только встретится ошибка - транзакция откатывается, не надо ничего самому проверять. После этого, если транзакция открыта явно, до COMMIT или ROLLBACK сервер будет ругаться и игнорировать твои запросы.
А вот возможность обрабатывать ошибки и делать SAVEPOINT/ROLLBACK TO SAVEPOINT появилась только в 8.0
Дмитрий Голубев
Дата: 11.11.2004 12:35:12
фффф

Про работу с транзакциями написано (сюрприз!) в официальной документации.
Функция всегда выполняется в транзакции, хочешь этого или нет. То, что ты описал - в функции работает по-умолчанию. Как только встретится ошибка - транзакция откатывается, не надо ничего самому проверять.


Согласен описано, и с этим то все понятно.


фффф

После этого, если транзакция открыта явно, до COMMIT или ROLLBACK сервер будет ругаться и игнорировать твои запросы.

Вот меня и интересует явное открытие транзакции и последующий ее откат.
Пожалуста хоть один примерчик явного открытия/закрытия транзакции в теле функции.

Спасибо
ффф
Дата: 11.11.2004 12:54:59
Т.к. функция всегда выполняется в транзакции, внутри функции открыть еще одну транзакцию нельзя. Откат при ошибке произойдет сам собой. А явное открытие - это только в клиентском приложении (или скрипте для psql):
create function test_fn() returns text as $_$
declare
  vI int;
begin
  select 1/0 into vI;
  return 'ok';
end;
$_$ language plpgsql;

begin;

select test_fn();
--ERROR:  division by zero
select now();
--ERROR:  current transaction is aborted, commands ignored until end of transaction block

commit; --или rollback - тут уже без разницы
Дмитрий Голубев
Дата: 11.11.2004 13:03:23
Огромное Спасибо !!!!