[s2container-php5:93] S2Dao.php5にて、バインド変数を持つクエリ中に日本語が含まれるとS2Dao_SQLRuntimeException

kuroda [E-MAIL ADDRESS DELETED]
2007年 4月 28日 (土) 22:40:57 JST


こんにちは、黒田です。

S2Container.PHP5-1.1.3
S2Dao.PHP5-1.1.2
MySql 5.0.22
PHP 5.1.6
CentOS 4.4
にて、エラーに遭遇しています。

Daoクラスに下記の様に日本語を含むクエリを記述し、
$dao->getFormatByNameList('a');
などと呼び出すと、

const getFormatByNameList_QUERY = 'formats.name = "日本語" or formats.name = /*name*/""';
public function getFormatByNameList($name = null);

下記のようにエラーが発生します。

Unexpected exception of type [S2Dao_SQLRuntimeException]
with message [SQLException occured, because SQLSTATE[42000]: 
Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your MySQL server version for 
the right syntax to use near '?' at line 1] in
[****/s2dao.php5/build/s2dao.php5/s2dao.core.classes.php line 538]

どこかで文字化けが発生している為、正常にバインド出来ていないのでしょうか?
使用しているファイルは全てutf-8です。

下記にように日本語を含むクエリであっても、バインド変数がない場合は問題ありません。

const getFormatByName2List_QUERY = 'formats.name = "日本語"';
public function getFormatByName2List();

また当然ながら、バインド変数に日本語の引数を与えても、クエリの記述自体に日本語が含まれていなければ問題ありません。
(ですので、日本語を使いたい場合は全てバインドしてしまうようにすれば、一応問題は回避できます。)
$dao->getFormatByName3List('日本語');

const getFormatByName3List_QUERY = 'formats.name = /*name*/""';
public function getFormatByName3List($name);


更に、別途下記にようなスクリプトを実行させてみましたが、これもエラーとはなりません。

<?php
$dsn = 'mysql:dbname=****;host=****';
$db = new PDO($dsn, '****', '****');

$sql = 'select * from formats where formats.name="日本語" or formats.name=?';

try{
	$db->beginTransaction();
	echo("sql " . $sql . "\n");

	$stmt = $db->prepare($sql);
	$stmt->bindValue(1, "a", PDO::PARAM_STR);
	$res = $stmt->execute();

	$db->rollback();
	echo("OK ");
} catch (PDOException $e) {
	echo 'transaction failed: ' . $e->getMessage();
	echo '    error code: ' . $e->getCode();
	$db->rollback();
	throw $e;
}


以上、回避策があるので問題無いと言えば問題無いのですが、
気味が悪いので報告させて頂きました。
では、よろしくお願いいたします。

黒田映史




S2Container-PHP5 メーリングリストの案内