Postgresql 过程 - 更新和 return 更新记录

Postgresql procedure - update and return updated records

我正在尝试编写一个简单的过程,它将像 queue - lock records (10 minutes) 和 return 那些锁定的记录一样工作。

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 用户,但事情并不像我期望的那样有效。任何帮助将不胜感激。

使用RETURNS RECORD(未知记录)不实用。请改用 OUT 变量。接下来 - 您修改 i_limit 行,但您 return 只有一个值。也许你想要 return 全部。:

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');

使用 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