バインド変数

セキュリティ対策、およびOracleにてSQL文の解析効率を向上させるために、
バインド変数(プレースホルダ)を指定するのは定石であるが、
自分の作成したプログラムを見直すと、キチンと出来ていない部分が多数…

以下は、Oracle に対するselect文を戻す関数。
テーブルカラムのセキュアな情報は、DBMS_OBFUSCATION_TOOL_KITを使って、
暗号化されている。CryptITはPL/SQLで書いたもの。

sub returnValue() {
	#- get argv
	my($tableName) = $_[0];           #- 表名称
	my($columnNameCondition) = $_[1]; #- 条件句のカラム名
	my($columnValueCondition) = $_[2];#- 条件句のカラム値
	my($columnNameSelect) = $_[3];
	my($addsql) = $_[4];
	my($res);
	my($data);

	my($SQL);
	#- 表、カラム名は大文字統一
	$tableName = uc ($tableName);
	$columnNameCondition = uc ($columnNameCondition);
	$columnNameSelect = uc ($columnNameSelect);

	##############
	#- 選択側
	##############
	if ( $columnNameSelect eq 'USER' ) { #- 個人情報だったら?
		$SQL = 'SELECT RTRIM(CryptIT.decrypt(' . $columnNameSelect . ', USER)) FROM ' . $tableName . ' ';
	} else {
		$SQL = 'SELECT RTRIM(' . $columnNameSelect . ') FROM ' . $tableName . ' ';
	}

	##############
	#- 条件句
	##############
	if ($columnNameCondition eq 'NAME') {
			#- 条件句に暗号化カラムが指定されている場合
			#- 検索はできない。させない。2004/08/10
			&poolDmlMsg('003', 'NotPermittedSelect'); #- メッセージ保存
			return ('');
	} else {
		$SQL .= ' WHERE ' . $columnNameCondition . ' = ?'; #- バインド変数
	}

	##############
	#- その他条件
	##############

	if (($addsql ne '') && ($addsql !~ /^\s+$/)) {
		$SQL .= ' AND ' . $addsql;
	}
	push (@SQLTRACEMSGS,$SQL);
	my ($STH) = $DBH->prepare($SQL);
	if ($DBI::errstr eq '') {
		$STH->{PrintError}=0;
		$STH->execute($columnValueCondition);
		while(($data) = $STH->fetchrow_array) {
			if ($data ne '') {
				$res = $data;
				last;
			}
		}
		$STH->finish;
	} else {
		&poolDmlMsg('002', 'DBSelect', $DBI::errstr, $SQL);
		$res = '';
	}
	return ($res);
}

また、DBにて暗号化されているデータを条件句とする検索は、
「暗号化文字列は、原則知られようがないため、アプリケーション(ひいてはユーザ)からの要求には応えない」
仕様とした。

正しいのかな?