CREATE OR REPLACE FUNCTION "Test"(character varying[],character varying[])
RETURNS refcursor AS
$BODY$
DECLARE
curr refcursor;
filter text;
counter integer;
BEGIN
counter = 1;
filter = '';
IF array_length($1,1) > 0 THEN
filter = 'AND ';
WHILE ($1[counter] <> '') LOOP
filter = filter||'LOWER('||$1[counter]||'::character varying) LIKE ''%''||LOWER($2['||counter||'])||''%'' AND ';
counter = counter + 1;
END LOOP;
filter = substring(filter FROM 1 FOR (char_length(filter)-4));
OPEN curr FOR
EXECUTE 'SELECT "Reservation".* FROM "Reservation" WHERE "Reservation"."id" > 0 '||filter;
return curr;
END IF;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
SELECT "Test"(ARRAY['"Reservation"."status"'],'{"waiting"}');
FETCH ALL IN "<unnamed portal 1>";
我试图打印出查询:
"SELECT "Reservation".* FROM "Reservation" WHERE "Reservation"."id" > 0 AND LOWER("Reservation"."status"::character varying) LIKE '%'||LOWER($2[1])||'%' "
但是当它被执行时它表示没有参数$ 2。所以我意识到它无法访问该存储过程的参数。
我不必担心sql注入的第一个参数,因为它是硬编码的。但第二个参数必须传递给执行。我该怎么做?
答案 0 :(得分:1)
我发现我可以使用“USING”语句将参数传递给EXECUTE。
这是最终的工作代码:
CREATE OR REPLACE FUNCTION "Test"(character varying[],character varying[])
RETURNS refcursor AS
$BODY$
DECLARE
curr refcursor;
filter text;
counter integer;
BEGIN
counter = 1;
filter = '';
IF array_length($1,1) > 0 THEN
filter = 'AND ';
WHILE ($1[counter] <> '') LOOP
filter = filter||'LOWER('||$1[counter]||'::character varying) LIKE ''%''||LOWER($1['||counter||'])||''%'' AND ';
counter = counter + 1;
END LOOP;
filter = substring(filter FROM 1 FOR (char_length(filter)-4));
OPEN curr FOR
EXECUTE 'SELECT "Reservation".* FROM "Reservation" WHERE "Reservation"."id" > 0 '||filter USING $2;
return curr;
END IF;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
SELECT "Test"(ARRAY['"Reservation"."status"'],ARRAY['no-show']);
FETCH ALL IN "<unnamed portal 1>";
请注意,我在EXECUTE语句中的值为$ 1,因为它接受$ 2作为其第一个参数。