0
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>"; 

내가 쿼리를 인쇄하려고 EXECUTE에 저장 프로 시저의 매개 변수를 전달하는 방법 :

"SELECT "Reservation".* FROM "Reservation" WHERE "Reservation"."id" > 0 AND LOWER("Reservation"."status"::character varying) LIKE '%'||LOWER($2[1])||'%' " 

을하지만 실행 때이 더 매개 변수 $ 2가 없다고 말했다. 그래서 그 저장 프로 시저의 매개 변수에 액세스 할 수 없다는 것을 알고 있습니다.

하드 코딩 된 이후 sql injection의 첫 번째 매개 변수에 대해 걱정할 필요가 없습니다. 그러나 두 번째 매개 변수는 실행에 전달되어야합니다. 어떻게해야합니까?

답변

1

"USING"문을 사용하여 EXECUTE에 매개 변수를 전달할 수 있다는 것을 알았습니다. 그것의 첫 번째 매개 변수로 $ 2 받아들이 때문에 나는, EXECUTE 문에서 값으로 $ 1이

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>"; 

참고 :

다음은 최종 작업 코드입니다.