powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обработка ошибок
16 сообщений из 16, страница 1 из 1
Обработка ошибок
    #33677737
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как при ошибке после INSERT-а в таблицу (если ключ уже существует)
сделать UPDATE вместо последнего?

Буду очень благодарен за вариант на plpgsql.

Спасибо!
...
Рейтинг: 0 / 0
Обработка ошибок
    #33677754
raul_83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все время делать два запроса:
UPDATE WHERE EXISTS
INSERT WHERE NOT EXISTS
...
Рейтинг: 0 / 0
Обработка ошибок
    #33678030
AlexCH12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну вот пример.

create or replace function _update (
_key integer
_name varchar(254)
) returns
integer
as
$$
declare
_c integer;
begin
select count(*) into _c from tab where k=_key;
if _c=0 then
insert into tab (k,n,tim_add) values (_key,_name,current_timestamp);
else
update tab set n=_name,tim_upd=current_timestamp where k=_key;
end if;
return 0;
end;
$$
language 'plpgsql' security definer;
...
Рейтинг: 0 / 0
Обработка ошибок
    #33678263
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
raul_83 ,AlexCH12
чему учите.. блин...


Igor Kozlov неслушай их :) делай так:


update ...
if affected rows=0 then
insert
end;
...
Рейтинг: 0 / 0
Обработка ошибок
    #33679445
KipDblK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wbear wrote:

> Igor Kozlov неслушай их :) делай так:
> update ...
> if affected rows=0 then
> insert
> end;

Можно еще использовать

if not found then ...

Этот вариант ИМХО даже в доках отражен.

--
Ego Liberare Art Ultimus Inuria
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Обработка ошибок
    #33682056
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем кто отозвался на мой вопрос.

2 wbear:

У меня почему-то не работает

if affected rows=0 then

(выдает ошибку возле rows)
К сожалению нигде в доках по plpgsql не шашел ничего подобного.

Сейчас попробую с IF NOT FOUND как КiрДык посоветовал...
...
Рейтинг: 0 / 0
Обработка ошибок
    #33682337
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это он нарно с GET DIAGNOSTICS ROW_COUNT попутал.
авторAn example:

GET DIAGNOSTICS integer_var = ROW_COUNT;

The second method to determine the effects of a command is to check the special variable named FOUND, which is of type boolean. FOUND starts out false within each PL/pgSQL function call. It is set by each of the following types of statements:

A SELECT INTO statement sets FOUND true if it returns a row, false if no row is returned.

A PERFORM statement sets FOUND true if it produces (and discards) a row, false if no row is produced.

UPDATE, INSERT, and DELETE statements set FOUND true if at least one row is affected, false if no row is affected.

A FETCH statement sets FOUND true if it returns a row, false if no row is returned.

A FOR statement sets FOUND true if it iterates one or more times, else false. This applies to all three variants of the FOR statement (integer FOR loops, record-set FOR loops, and dynamic record-set FOR loops). FOUND is set this way when the FOR loop exits; inside the execution of the loop, FOUND is not modified by the FOR statement, although it may be changed by the execution of other statements within the loop body.

FOUND is a local variable within each PL/pgSQL function; any changes to it affect only the current function.
...
Рейтинг: 0 / 0
Обработка ошибок
    #33682367
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо 4321.

Я почему-то до этого не дочитался.

Вот теперь пробую сделать функцию, но она не компилируется.
(Выдает ошибку в нижеуказанных строках)


DECLARE
nm ALIAS FOR $1;
dsc ALIAS FOR $2;
BEGIN
UPDATE units SET description = dsc WHERE name = nm; -- ВЫДАЕТ ОШИБКУ
IF found THEN
RETURN -1;
END IF;
INSERT INTO units (name, description) VALUES (nm, dsc); -- ВЫДАЕТ ОШИБКУ
RETURN 0;
END;

Помогите разобраться, ПЛЗ.
...
Рейтинг: 0 / 0
Обработка ошибок
    #33682438
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor KozlovСпасибо 4321.

Я почему-то до этого не дочитался.

Вот теперь пробую сделать функцию, но она не компилируется.
(Выдает ошибку в нижеуказанных строках)


DECLARE
nm ALIAS FOR $1;
dsc ALIAS FOR $2;
BEGIN
UPDATE units SET description = dsc WHERE name = nm; -- ВЫДАЕТ ОШИБКУ
IF found THEN
RETURN -1;
END IF;
INSERT INTO units (name, description) VALUES (nm, dsc); -- ВЫДАЕТ ОШИБКУ
RETURN 0;
END;

Помогите разобраться, ПЛЗ. какую, простите ошибку? неужели трудно прочитать?
пока не занем, но предположительно надо взять служебные слова (ежели таие есть) в наименовании полей в кавыки. "units" ("name", "description")
...
Рейтинг: 0 / 0
Обработка ошибок
    #33682468
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Простите дурака, - забыл ошибку описать.

Вот "копия":

pgAdmin III

An error has occured:

ERROR: syntax error at or near "$1" at character 19
QUERY: UPDATE units SET $1 = $2 WHERE $3 = $4
CONTEXT: SQL statement in PL/PgSQL function "merge_units" near line 5

Самое странное то, что эти запросы работают с SQL-редактора, а в функции - выдает вишеуказанную ошибку.
...
Рейтинг: 0 / 0
Обработка ошибок
    #33683188
wbear
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пиршли плз всю функцию целиком начиная CREATE и заканчивая последней ;
...
Рейтинг: 0 / 0
Обработка ошибок
    #33683630
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот она:
(Строки где выдает ошибки - закоментарены)


-- Function: merge_units(name text, description text)

-- DROP FUNCTION merge_units(name text, description text);

CREATE OR REPLACE FUNCTION merge_units(name text, description text)
RETURNS bool AS
$BODY$
DECLARE
nm ALIAS FOR $1;
dsc ALIAS FOR $2;
BEGIN
-- UPDATE units SET description = dsc WHERE "name" = nm;
IF found THEN
RETURN -1;
END IF;
-- INSERT INTO units (name, description) VALUES (nm, dsc);
RETURN 0;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION merge_units(name text, description text) OWNER TO postgres;
...
Рейтинг: 0 / 0
Обработка ошибок
    #33683650
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а чо хочешь то?

ежели ты перекрыл имена полей таблиц именами переменных - то просто напиши например
CREATE OR REPLACE FUNCTION merge_units(_name text, _description text)

а если просто "хочешь странного" - то тады подумай, чого хочешь, а потом формулируй вопрос не про функцию, а "как сделать странное".
...
Рейтинг: 0 / 0
Обработка ошибок
    #33683660
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и вообще неясно,зачем 2 раза определять (к тому же разные) алиасы к одним и тем же переменным (и в объявлении ф-ии, и в DECLARE). уш как нибуть разберитесь.
...
Рейтинг: 0 / 0
Обработка ошибок
    #33683786
Igor Kozlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да... я действительно ДУРАК.

СПАСИБО что просветил, - теперь я обязательно исправлюсь :)
...
Рейтинг: 0 / 0
Обработка ошибок
    #33709835
Serik Akhmetov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно сделать RULE

-- Rule: "rule_directory_i ON directory"
-- DROP RULE rule_directory_i ON directory;

CREATE OR REPLACE RULE rule_directory_i AS
ON INSERT TO directory
WHERE (EXISTS ( SELECT directory.id_directory FROM directory
WHERE directory.id_directory = new.id_directory))
DO INSTEAD
UPDATE directory SET id_directory = new.id_directory,
ip_update_host = new.ip_update_host
WHERE directory.id_directory = new.id_directory;
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обработка ошибок
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]