I am trying to write a function that takes an ID as an input and update some fields on that given ID. So far, it looks like this:
CREATE FUNCTION update_status(p_id character varying,
p_status character varying DEFAULT NULL::character varying) RETURNS character varying
LANGUAGE plpgsql
AS
$$
DECLARE
v_row_count bigint DEFAULT 0;
v_result varchar(255);
BEGIN
IF p_id IS NOT NULL THEN
SELECT count(user_id)
INTO v_row_count
FROM test
WHERE user_id = p_id;
END IF;
IF v_row_count <= 0 THEN
v_result = 'User not found';
RETURN v_result;
ELSE
IF p_id NOT LIKE '%,%' THEN
UPDATE test
SET status = p_status,
updated_by = 'admin'
WHERE user_id IN (p_id);
ELSE
--Here comes split and pass multiple IDs into an IN() operator
END IF;
END IF;
END
$$;
ALTER FUNCTION update_status(varchar, varchar) OWNER TO postgres;
Now, it is supposed to accept only one ID at a time but I wonder if I can get it to also accept multiple IDs -maybe even hundreds- once by splitting that single string into an array of IDs if it has a comma delimiter, then pass those to an IN() operator. How can I get split a string into an array so I can feed it to an IN() operator?
Blue Star already mentioned that there is a built-in function to convert a comma separated string into an array.
But I would suggest to not pass a comma separated string to begin with. If you want to pass a variable number of IDs use a variadic parameter.
You also don't need to first run a SELECT, you can ask the system how many rows were updated after the UPDATE statement.
CREATE FUNCTION update_status(p_status text, p_id variadic integer[])
RETURNS character varying
LANGUAGE plpgsql
AS
$$
DECLARE
v_row_count bigint DEFAULT 0;
BEGIN
UPDATE test
SET status = p_status,
updated_by = 'admin'
WHERE user_id = any (p_id);
get diagnostics v_row_count = row_count;
if v_row_count = 0 then
return 'User not found';
end if;
return concat(v_row_count, ' users updated');
END
$$;
You can use it like this:
select update_status('active', 1);
select update_status('active', 5, 8, 42);
If for some reason, you "have" to pass this as a single argument, use a real array instead:
CREATE FUNCTION update_status(p_status text, p_id integer[])
Then pass it like this:
select update_status('active', array[5,8,42]);
or
select update_status('active', '{5,8,42}');
There's a function for that, see docs.
SELECT string_to_array('str1,str2,str3,str4', ',');
string_to_array
-----------------------
{str1,str2,str3,str4}
Note that once it's an array, you'll want your condition to look like this -
WHERE user_id = ANY(string_to_array(p_id, ',');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With