开发者

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[] )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜