PLPGSQL how to use an array in a execute statement?
I have a plpgsql function that executes a query, but when i put an array into it it wont parse it, at least it gives me this error:
[FAIL] syntax error at or near "{"
LINE 21: AND c.category_uuid != ANY({"c0857e20-111e-11e0-ac64-0800...
CONTEXT: PL/pgSQL function "get_membercategories" line 22 at FOR over EXECUTE statement
This is the complete line:
AND c.category_uuid != ANY({"c0857e20-111e-11e0-ac64-0800200c9a66"})
This is how my function looks
CREATE OR REPLACE FUNCTION get_membercategories(in_company_uuid uuid, in_parent_uuid uuid, in_start integer, in_limit integer, in_sortby character varying, in_order character varying, in_querystring character varying, IN in_excludestring UUID[], OUT out_status integer, OUT out_status_description character varying, OUT out_value character varying[]) RETURNS record
LANGUAGE plpgsql
AS $$
DECLARE
temp_record RECORD;
altered_parent_uuid UUID;
temp_out_value VARCHAR[];
temp_iterator INTEGER := 0;
temp_parent_uuidstring VARCHAR;
temp_excludestring VARCHAR := '';
BEGIN
IF in_parent_uuid IS NOT NULL THEN
temp_parent_uuidstring := 'AND c.parent_uuid = ''' || in_parent_uuid || '''';
ELSE
temp_parent_uuidstring := 'AND c.parent_uuid IS NULL';
END IF;
IF in_excludestring IS NOT NULL THEN
temp_excludestring := 'AND c.category_uuid != ANY(' || in_excludestring || ')';
END IF;
FOR temp_record IN EXECUTE '
SELECT
c.name,
c.category_uuid,
mc.password,
(
SELECT COUNT(*)
FROM
targetgroupusers tgu
WHERE
tgu.targetgroup开发者_如何学C_uuid = mc.targetgroup_uuid
) AS receivers
FROM
membercategories AS mc
LEFT JOIN
categories AS c
ON
mc.category_uuid = c.category_uuid
WHERE
c.isdeleted IS NULL
' || temp_excludestring || '
AND
mc.company_uuid = ''' || in_company_uuid || '''
' || in_querystring || '
' || temp_parent_uuidstring || '
ORDER BY
' || in_sortby || ' ' || in_order || '
OFFSET
' || in_start || '
LIMIT
' || in_limit
LOOP
temp_out_value[temp_iterator] = ARRAY[temp_record.category_uuid::VARCHAR(36), temp_record.name::CHARACTER VARYING, temp_record.receivers::CHARACTER VARYING, CASE WHEN temp_record.password IS NOT NULL THEN '1' ELSE '0' END];
temp_iterator = temp_iterator+1;
END LOOP;
out_status := 0;
out_status_description := 'Member categories successfully retrieved';
out_value := temp_out_value;
RETURN;
END$$;
I am clueless at this point, any help is very much appreciated!
Your problem is that the the array gets expanded to an invalid string (as you can see in the error message). The string representation of an array needs to be enclosed into single quotes again and then casted to the approriate array type:
The following should work:
IF in_excludestring IS NOT NULL THEN temp_excludestring := 'AND c.category_uuid != ANY(''' || in_excludestring::varchar||'''::UUID[])'; END IF;
Note that in_excludestring is explicitely cast to a varchar to force the string representation of an array, enclosed in single quotes to satisfy the "array literal" syntax and then cast back to an UUID array.
The resulting string will look something like this:
category_uuid != ANY ( '{c0857e20-111e-11e0-ac64-0800200c9a66,7fffda0c-11c9-11e0-967c-a300aec7eb54}'::UUID[] )
精彩评论