I have a stored procedure in which I need to query for a set of ids
and then use that set in an UPDATE
statement's WHERE
clause. I'm using PostgresQL 9.0+. I'd rather not use a loop over the set of ids
and issue multiple UPDATE
statements -- that's not very efficient.
Here's a simple example:
CREATE OR REPLACE FUNCTION test_it()
RETURNS VOID AS $$
DECLARE
cur_time TIMESTAMP;
ids a%ROWTYPE;
BEGIN
SELECT id FROM a INTO ids;
UPDATE b
SET state = 'foobar', updated_at = cur_time
WHERE id IN ids;
END;
$$ LANGUAGE plpgsql;
This doesn't even compile.
I've also tried SELECT-ing the ids
like so...
CREATE OR REPLACE FUNCTION test_it()
RETURNS VOID AS $$
DECLARE
cur_time TIMESTAMP;
ids a%ROWTYPE;
BEGIN
SELECT id FROM a INTO ids;
UPDATE b
SET state = 'foobar', updated_at = cur_time
WHERE id IN (SELECT ids);
END;
$$ LANGUAGE plpgsql;
This throws an error: HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
My actual stored proc is a lot more complicated because the initial query for the set of ids
is actually a dynamic query.
The actual error output is this (just more context...):
ERROR: operator does not exist: integer = task_responses
LINE 3: WHERE id IN (SELECT task_response_ids)
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
QUERY: UPDATE task_responses
SET state = state, updated_at = cur_time, rejected_at = cur_time
WHERE id IN (SELECT task_response_ids)
CONTEXT: PL/pgSQL function "reject_submissions_with_comment" line 38 at SQL statement