powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите нацарапать функцию
10 сообщений из 10, страница 1 из 1
Помогите нацарапать функцию
    #35584012
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помогите пож. быстро и правильно написать на postgre нечто подобное оракловому коду. (прошу за оракловый код ногами не пинать, знаю что можно написать подругому)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create function applyMyTable(pid number, ptext varchar2, premark varchar2) return mytable%rowtype as
  cnt number;
  newid number;
  ret mytable%rowtype
begin
   select count(*)  into cnt
    from mytable where id = pid;

    if cnt =  0  then
       select seq.nextval  into newid;
       insert  into mytable  values  (newid,ptext,premark);
    else 
       newid := pid;
       update mytable  set text=ptext, remark=premark  where id = pid; 
    end if;
    
    select *  into ret
     from myTable where id=newid;
 
   return ret
end;
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584109
Фотография Warstone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE OR REPLACE FUNCTION applyMyTable(IN pid bigint, IN ptext text, IN premark text)
RETURNS SETOF mytable AS
$BODY$
DECLARE
  cnt bigint;
  newid bigint;
BEGIN
  SELECT Count(*) INTO newid FROM mytable WHERE id = pid;
  IF cnt =  0  THEN
    SELECT NEXT VALUE ('seq') INTO newid;
    INSERT INTO mytable VALUES(newid, ptext, premark);
  ELSE
    newid := pid;
    UPDATE mytable SET text=ptext, remark=premark WHERE id = pid;
  END IF;
  RETURN QUERY SELECT * FROM mytable WHERE id=newid;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST  100 
  ROWS  1000 ;
Возможно придется сделать
Код: plaintext
CREATE LANGUAGE 'plpgsql';
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584119
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
большое спасибо.
сделал,
помоги запустить
ругается как


Код: plaintext
1.
2.
3.
4.
5.
select applyTable( 1 ,'qwe','qwe')
ERROR:  function applyTable(integer, unknown, unknown) does not exist

начало определения:
CREATE OR REPLACE FUNCTION public."applyTable"(int4, varchar, varchar)
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584136
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ERROR: syntax error at or near "12"
LINE 1: select applyTable(bigint 12,varchar 'a',varchar 'b')
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584199
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибка была:
Редактор кастил запрос, опускал имя функции в нижний регистр и выполнял
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584563
ЯЕХХ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, что в оракле, что в постгресе у вас в некоторых случаях функция будет работать некорректно.

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

Надёжней было бы в блоке BEGIN ... EXCEPTION попытаться вставить строку, а если возникло unique_violation - сделать UPDATE

В версии 8.3 можно написать коротко и ясно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create or replace function applyMyTable(pid int, ptext text, premark text) returns setof mytable --!!! set вместо record
language plpgsql as $body$
begin
  --!!! pid=NULL - генерация нового значения
  return query insert into mytable values (coalesce(pid,nextval('myseq')), ptext, premark) returning *;
exception
  when unique_violation then
    return query update mytable set text=ptext, remark=premark where id=pid returning *;
end;
$body$;


...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584804
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЯЕХХКстати, что в оракле, что в постгресе у вас в некоторых случаях функция будет работать некорректно.

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

Надёжней было бы в блоке BEGIN ... EXCEPTION попытаться вставить строку, а если возникло unique_violation - сделать UPDATE

В версии 8.3 можно написать коротко и ясно:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create or replace function applyMyTable(pid int, ptext text, premark text) returns setof mytable --!!! set вместо record
language plpgsql as $body$
begin
  --!!! pid=NULL - генерация нового значения
  return query insert into mytable values (coalesce(pid,nextval('myseq')), ptext, premark) returning *;
exception
  when unique_violation then
    return query update mytable set text=ptext, remark=premark where id=pid returning *;
end;
$body$;




Спасибо, собственно нечто подобное я и хотел увидеть.
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35584843
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите ещё плиз - как правильно разбить строчку
Код: plaintext
1.
return query insert into mytable values (coalesce(pid,nextval('myseq')), ptext, premark) returning *;

на нечто подобное

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
declare
  qr ?????
begin
........
insert into mytable values (coalesce(pid,nextval('myseq')), ptext, premark) returning * into qr;
return query qr
.......
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35585289
ЯЕХХ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ksm80Подскажите ещё плиз - как правильно разбить строчку
........

Так просто не выйдет. На выходе RETURNING набор строк, а переменных типа таблиц в Постгресе нет :(
Цикл FOR r IN (INSERT .. RETURNING) не работает :((
Максимум что придумал
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
declare
  qr mytable%rowtype;
begin
  qr := ROW(coalesce(pid,nextval('myseq')), ptext, premark);
  insert into mytable select qr.*;
  return next qr;
...
...
Рейтинг: 0 / 0
Помогите нацарапать функцию
    #35585489
ksm80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спас за ещё пару приёмов
я сделал так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
declare
  ret mytab%rowtype;
begin
  begin
       insert 
       into mytab(id, text, remark)
       values (nextval('seqid'), ptext, premark)
       returning * into ret;
  exception
    when unique_violation then
       update myTab 
       set text=ptext, remark=premark
       where id=pid  
       returning * into ret;
  end;
  return next ret;
end;
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите нацарапать функцию
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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