PL/SQLで動的SQLにバインド変数を使う

SQLインジェクション対策として。

str := '''%CLERK''';
execute immediate 'select job_id from jobs where job_id like ' || str bulk collect into job_ids;
dbms_output.put_line(job_ids.count);
# => 3

str := '''%CLERK'' or 1 = 1';
execute immediate 'select job_id from jobs where job_id like ' || str bulk collect into job_ids;
dbms_output.put_line(job_ids.count);
# => 19

str := '''%CLERK'' or 1 = 1';
execute immediate 'select job_id from jobs where job_id like :param' bulk collect into job_ids using str;
dbms_output.put_line(job_ids.count);
# => 0

select
  job_id
bulk collect into
  job_ids
from
  jobs
where
  job_id like str
;
dbms_output.put_line(job_ids.count);
# => 0

1つめがインジェクションされないやつ、2つめがインジェクションされてしまったやつ、3つめがバインド変数を使ったやつ、4つめが静的SQLのやつ(変数がそもそもSQLとして解釈されない)。

参考