[s2container-php5:40] Re: S2Daoでのselect ... insert intoの実行に関して

Yusuke Hata nowel @ xole.net
2006年 7月 4日 (火) 02:05:46 JST


ハタです。

> > # 手元にwindows機が無いのですが、Win32のPDOはあまり良い動きをしてくれなかったのを記憶しています。
> > # 機会があればWindows版でも試してみます。
> 
> 確かにPDOの挙動はおかしいような気がします。

案外PDOじゃなくてMySQL(とか色々なDBMS)側の問題もありそうな気もしますが
動作が統一されてないと難しいですね.... ^^;;

> そこで、ついでにといっては何ですが、insert into絡みで、
> もう一点疑問があります。
> 出力先ファイルを動的に決定したいと思い、
> 
>      const outputAll_SQL = "select * into outfile /*file*/
>      fields terminated by '\t' from some_table";
>      public function outputAll($file);
> 
> として
> outputAll("/tmp/out.txt")などと呼び出すと、
> こちらもやはりwindowsでは成功し、FreeBSDではエラーとなります。
> これについては、そもそもPDOの仕様であるのか、
> 例えば下記のようなスクリプトを実行すると
> prepareに失敗し、
> var_dumpは
> bool(false)
> を出力します。
> 

<skip>

> 色々試しましたが、
> どうやらinto outfileの後にパラメータ(疑問符パラメータ、名前つきパラメータどちらも)
> を置くことは出来ないようです。
> windowsで成功するのが"たまたま"なのか、
> FreeBSD側のPDOがおかしいのか、この他の環境がないので判断出来ないのですが、
> 他の環境で再現するかどうかだけでも分かると助かるのですが・・・。
> そもそも、PDOというよりもMySQLのプリペアドステートメントの扱いに
> 問題があるのかも知れません。
> (PDOが内部でmysql_stmt_prepare()を使っているようなので、そこら辺かな・・・と。)

こちらに関してはPDO::ATTR_EMULATE_PREPARESで対応できると思います。
PHP5.1.3から対応しており、いくつかの発行不可能なプリペアステートメントを発行可能に
エミュレートしてくれます。

また、以下のように書いてみました。

<?php
$pdo = new PDO("mysql:host=localhost; dbname=s2con", "root", "pass");
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

$sql = "SELECT * into outfile ? FROM CD";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(1, "/tmp/hoge.txt");
var_dump($stmt->execute());
?>

前回と同じくSuSE10.1で確認しましたが、ちゃんと発行されているみたいです。
# var_dumpもtrueでした。

あと、プリペアドステートメントに関してはステートメント発行時に含めなければならないものは
プリペア発行時に失敗します。
# 例えば SELECT * FROM ? とかは失敗します。

現在S2Dao.PHP5では上記のPDO::ATTR_EMULATE_PREPARESの対応を行っていません。
ずいぶん前から適用しようと思っていますが、なかなか進んでいません…もうしばらくお待ちください。

> 
> さて、パラメータが使用出来ないとなると、
> 出力先ファイルを動的に変化させるにはどうするべきでしょうか?
> よろしくお願いいたします。

こちらに関しては、MySQLですと、Stored Function/Procedureを使うのが良いと思います。
PROCEDUREアノテーションにてINパラメータに対応していますので、そちらで対応可能だと思います。
http://s2dao.php5.sandbox.seasar.org/reference.html#ProcedureAnnotation

といってもMySQL4.1.20とのことですので、S2Dao.PHP5の対応待ちですね…
早めに対応しますのでもうしばらくお待ちください。m(_ _)m

もしくは、データ量にもよりますが、出力結果をfile_put_contents等で書き込む等
PHP側で対応していただくしかないと思います。

以上です。

-- 
Yusuke Hata <nowel @ xole.net>
blog: http://blog.xole.net/


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