Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите нацарапать функцию / 10 сообщений из 10, страница 1 из 1
08.10.2008, 18:14
    #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
08.10.2008, 19:06
    #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
08.10.2008, 19:12
    #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
08.10.2008, 19:26
    #35584136
ksm80
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите нацарапать функцию
ERROR: syntax error at or near "12"
LINE 1: select applyTable(bigint 12,varchar 'a',varchar 'b')
...
Рейтинг: 0 / 0
08.10.2008, 20:01
    #35584199
ksm80
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите нацарапать функцию
Ошибка была:
Редактор кастил запрос, опускал имя функции в нижний регистр и выполнял
...
Рейтинг: 0 / 0
09.10.2008, 03:52
    #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
09.10.2008, 10:21
    #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
09.10.2008, 10:31
    #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
09.10.2008, 12:37
    #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
09.10.2008, 13:29
    #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
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите нацарапать функцию / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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