0

I am trying to combine the following two sql statements in my application code into a function in postgresql, but I'm having some trouble. Here are the two sql queries I'd like to combine:

UPDATE userrange f 
SET UsedYesNo = true, user_id=user_id, updateddatetime=now()
WHERE f.uservalue IN(
    SELECT a.uservalue FROM userrange a WHERE UsedYesNo=false Order By id ASC Limit 1)
    RETURNING a.uservalue;

The results from the above statement are used in this query:

   INSERT INTO widget 
   VALUES(DEFAULT, uservalue, 'test','123456778',1,"testservername", now(), Null)

So far, I've built function that just does the first update statement, like so:

CREATE or REPlACE FUNCTION create_widget(IN user_id integer, IN password character varying DEFAULT NULL::character varying)
  RETURNS TABLE(uservalue integer) AS
$BODY$
BEGIN

    RETURN QUERY
UPDATE userrange f SET UsedYesNo = true, user_id=user_id, updateddatetime=now()
    WHERE f.uservalue IN(
    SELECT a.uservalue FROM userrange a WHERE UsedYesNo=false Order By id ASC Limit 1)
    RETURNING a.uservalue;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE

It compiles but when I execute it, it fails with the error:

ERROR:  missing FROM-clause entry for table "a" LINE 4:  RETURNING a.uservalue

I'm just googling this error to see how I can fix it... but could I just create a variable called uservalue in a DECLARE section and use it in the secondary query? Or can i combine the sql into one

thanks.

4

1 回答 1

1

如果您可以放弃该功能并且您拥有 PostgreSQL 9.2+,则可以在单个查询中进行更新和插入。如有必要,将其移植到函数应该很简单。

WITH f AS (
    UPDATE userrange f
    SET UsedYesNo = true, user_id=user_id, updateddatetime=now()
    WHERE UsedYesNo IS FALSE
    RETURNING f.uservalue)
INSERT INTO widget (<column list>)
SELECT f.uservalue, 'test','123456778',1,"testservername", now(), NULL
FROM f;

-- [编辑:添加功能] -- 注意:以下功能未经测试

CREATE OR REPLACE FUNCTION create_widget(IN p_user_id INTEGER, IN p_password VARCHAR DEFAULT NULL::VARCHAR)
RETURNS TABLE(uservalue integer) AS
$BODY$
BEGIN
    RETURN QUERY
        WITH f AS (
            UPDATE userrange f
            SET UsedYesNo = true,
                user_id = p_user_id,
                updateddatetime = now()
            WHERE UsedYesNo IS FALSE
            RETURNING f.uservalue)
        INSERT INTO widget (<column_list>)
        /*  Omit the DEFAULT, by not including it in the column list above,
        *   the DEFAULT already defined on the column will be used.
        */
        SELECT f.uservalue, 'test','123456778',1,"testservername", now(), NULL
        FROM f;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
于 2013-08-02T15:06:38.217 回答