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

クエリを印刷しようとしました:

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

しかし、それが実行されたとき、それはパラメータ$2がなかったと言いました。そのため、そのストアドプロシージャのパラメータにアクセスできないことに気付きました。

SQLインジェクションの最初のパラメーターはハードコーディングされているため、心配する必要はありません。ただし、2番目のパラメータを実行に渡す必要があります。それ、どうやったら出来るの?

4

1 に答える 1

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を受け入れるためです。

于 2013-01-21T10:36:09.937 に答える