Postgresql过程 - 更新并返回更新的记录

时间:2015-03-16 08:46:56

标签: postgresql stored-procedures

我试图编写一个像queue - lock records (10 minutes)一样的简单程序,然后返回那些锁定的记录。

CREATE OR REPLACE FUNCTION select_queue(
    i_limit integer,
    i_sessionid text)
  RETURNS RECORD AS
 $BODY$
 declare match_ret record;
 BEGIN

 SELECT userid,date,description INTO match_ret FROM table
 WHERE (lock_session IS NULL AND lock_date IS NULL) OR lock_date < NOW() - INTERVAL '10 MINUTE' LIMIT i_limit FOR UPDATE;

 UPDATE table SET lock_session=i_sessionid, lock_date=NOW() WHERE userid=match_ret.userid;

 RETURN match_ret;
 END;
 $BODY$
 LANGUAGE plpgsql

我是MySQL用户,事情并没有像我期望的那样发挥作用。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

使用RETURNS RECORD(未知记录)是不切实际的。请改用OUT变量。下一步 - 您修改i_limit行,但只返回一个值。也许你想要全部归还。:

CREATE OR REPLACE FUNCTION select_queue(i_limit int,i_sessionid text,
                                        OUT o_userid int, OUT o_date, o_desc text) 
   RETURNS SETOF RECORD AS $$
DECLARE _row_id int;
BEGIN
   FOR _row_id, o_userid, o_date, o_desc IN
             SELECT row_id, userid,date,description 
                FROM table
               WHERE (lock_session IS NULL AND lock_date IS NULL) 
                  OR lock_date < NOW() - INTERVAL '10 MINUTE' 
               LIMIT i_limit FOR UPDATE
   LOOP
      UPDATE table SET lock_session=i_sessionid, lock_date=NOW() 
         WHERE row_id = _row_id;
      RETURN NEXT;
   END LOOP;
   RETURN;
END
$$ LANGUAGE plpgsql;

您可以使用SELECT调用此功能:

SELECT * FROM select_queue(10, 'safdsdfsfds');

答案 1 :(得分:0)

使用PostgresQL一天之后,这就是我创造的:

 CREATE OR REPLACE FUNCTION api.get_user_photo(
    IN i_limit integer,
    IN i_sessionid text,
    IN i_main integer,
    OUT list refcursor,
    OUT elapsed real,
    OUT all_count integer,
    OUT userids bigint[])
  RETURNS record AS
$BODY$
DECLARE
    _tstart       timestamp with time zone;
    _max_date     timestamp with time zone;
    _ids      bigint[];
    _locked       integer;
BEGIN
    _tstart = clock_timestamp();
    _max_date = NOW() - INTERVAL '5 MINUTE';

    -- check for already locked photo
    SELECT count(1) INTO _locked FROM core.user_photos
        WHERE lock_sessionid=i_sessionid;

    IF _locked <> 0 THEN
        i_limit = i_limit - _locked;
    END IF;

    UPDATE core.user_photos
    SET lock_sessionid=i_sessionid, lock_date=NOW() 
    WHERE id in (
        SELECT id FROM core.user_photos
        WHERE (lock_sessionid IS NULL AND lock_date IS NULL AND main=i_main) 
        OR (lock_date < _max_date AND main=i_main) 
        LIMIT i_limit
    );  

    -- Count locked records
    SELECT count(1) INTO all_count
    FROM core.user_photos
    WHERE lock_sessionid=i_sessionid;

    -- Get unique ids
    SELECT array_agg(distinct userid) INTO userids
    FROM core.user_photos
    WHERE lock_sessionid=i_sessionid;

    -- Get locked photo
    OPEN list FOR
        SELECT id AS moderation_id,userid,description,md5,ext,transform,main_moderation,moderation,desc_moderation
        FROM core.user_photos
        WHERE lock_sessionid=i_sessionid;

    elapsed := EXTRACT('epoch' FROM clock_timestamp() - _tstart)::real;
    RETURN;
END
$BODY$
  LANGUAGE plpgsql