Access の全クエリーの SQL から文字列検索
Access 2000 で、あるテーブルがどのクエリーで使われているかを調べようと思ったのですが、クエリーの数が非常に多く、デザインビューなどで1つ1つ開いて調べるのはやっかい、という場面に出くわしました。
そこで調べてみると、クエリーの SQL をテキストファイルに出力するサンプルを紹介してくれている方がいました。これを使えば、出力したテキストファイル内を検索すれば調べられます。
http://questionbox.jp.msn.com/qa708589.html
以下はプログラムそのままの引用になります。クエリーを読み取ってテキストファイルに出力し、それをメモ帳で開いています。
Private Sub Command_Click() Dim Dbs As DAO.Database Dim Qdf As DAO.QueryDef Dim FileName As String Dim FNum As Integer Dim stSQL As String Dim ret As Double 'データベースセット Set Dbs = CurrentDb 'Set Dbs = DAO.OpenDatabase("c:\test.mdb") 'ファイルを開く FNum = FreeFile FileName = Mid(Dbs.Name, InStrRev(Dbs.Name, "\") + 1) FileName = Left(FileName, InStrRev(FileName, ".") - 1) FileName = "c:\" & FileName & "_Query.txt" Open FileName For Output Access Write As #FNum 'クエリ分ループ For Each Qdf In Dbs.QueryDefs 'クエリ名&SQLステートメント取得 stSQL = "QueryName:" & Qdf.Name & vbCrLf & _ "SQL:" & Qdf.SQL & vbCrLf & vbCrLf 'ファイルに出力 Print #FNum, stSQL Next Set Dbs = Nothing Close #FNum 'ファイルを開く(notepad.exe) ret = Shell("notepad.exe " & FileName, vbNormalFocus) End Sub
Windows→Linuxへ自動ファイル転送
ローカルのWindows端末でコーディングしたファイルをLinuxサーバ等に転送して動作確認するようなシステム開発の場合、毎回転送ソフトを使って手作業で転送するのは結構手間になります。何か良いツールはないものかと調べたところ、SSHでファイル転送してくれるWinSCPを使えば更新したファイルだけ自動転送できることがわかりました。
ミラーリングアップロードを開始させておくと、ローカルのファイルの追加・修正・削除を検知して即時にサーバへ反映してくれます。これはかなり使えそうです。ただし、ファイル数が500個以上になると検知が遅くなってくるようです。
設定方法は、下記サイトのミラーリングの項目に記載があります。
▼WinSCP3の使い方
http://osksn2.hep.sci.osaka-u.ac.jp/~naga/miscellaneous/winssh/winsshb1.html
Zend Framework のセッション有効期限
ログイン認証を行うWebアプリは適切にセッション有効期限を設定する必要がありますが、Zend Framework(1.9.2)の Zend_Auth を使うと、ログインしてから一定時間経過後にセッションが切断されるとのこと。
そうではなく、最後にアクセスした後一定時間放置したらセッションが切断されるようにしたかったのですが、そのような機能は用意されていないようです。
実現するシンプルで良さそうな方法が見つからなかったのですが、以下のようにすると出来ます。
$authSession = new Zend_Session_Namespace('Zend_Auth'); $authSession->setExpirationSeconds(600);
これを毎度のアクセスの度に実行するようにしておけば、アクセスの度に有効期限を更新できるというわけです。
正当な方法という感じはしないですが、とりあえずこれで・・・。
Zend Framework+MySQLの文字化け対策
PHP5 + Zend Framework 1.9.2 + MySQL5 で、DBからデータを取得したときに文字化けするのを防ぐ方法について。
以下のように「set names utf8」を先に発行しておけば文字化けは防げるが、汎用的な Zend_Db を使っている以上、やはり MySQL 特有のコマンドは使いたくないしSQLインジェクションを引き起こす可能性があります。(参考 SET NAMESは禁止:http://blog.ohgaki.net/set_namesa_mcb_asc)
$db = Zend_Db::factory('Pdo_Mysql', array( 'host' => 'xxx.xxx.xxx.xxx', 'username' => 'xxx', 'password' => 'xxx', 'dbname' => 'xxx' )); $db->query("set names utf8");
そこで調べてみると、factory() のパラメータに charset を指定できることが判明。以下のようにすると、文字化けを防ぐことができました。
$db = Zend_Db::factory('Pdo_Mysql', array( 'host' => 'xxx.xxx.xxx.xxx', 'username' => 'xxx', 'password' => 'xxx', 'dbname' => 'xxx', 'charset' => 'utf8' ));
これでよしよし・・・と思ったのですが、念のため Zend Framework のソースコード(Zend/Db/Adapter/Pdo/Mysql.php)を見てみると、「set names xxx」を使っているじゃないですか! PDO の driver_options パラメータに「set names xxx」を渡していました。SQLインジェクションは大丈夫なのでしょうか・・・?
以下がソースコードの一部引用です。
protected function _connect() { if ($this->_connection) { return; } if (!empty($this->_config['charset'])) { $initCommand = "SET NAMES '" . $this->_config['charset'] . "'"; $this->_config['driver_options'][1002] = $initCommand; // 1002 = PDO::MYSQL_ATTR_INIT_COMMAND } parent::_connect(); }
ちょっと不安なので、Pdo_Mysql ではなく Mysqli を使うことに。これで文字化けせずにうまく動きました。
$db = Zend_Db::factory('Mysqli', array( 'host' => 'xxx.xxx.xxx.xxx', 'username' => 'xxx', 'password' => 'xxx', 'dbname' => 'xxx', 'charset' => 'utf8' ));
Mysqli の ソースコード(Zend/Db/Adapter/Mysqli.php)を見ると、mysqli_set_charset() で文字コードをセットしていました。これを使えば、SQLインジェクションは大丈夫なようです。
Socket通信でレスポンスが遅い
PHP プログラムで Web サーバと SSL 通信すると非常にレスポンスが遅くなるという
現象に出くわしたので、その対処方法を書いておきます(HTTP通信でも同じ現象になるかもしれません)。
fsockopen() で 443 ポートに接続し、データを送受信する以下のプログラムでは、レスポンスが遅くなります。
$send_data = '送信データ'; $fp = @fsockopen("ssl://192.168.0.xxx", 443, $errno, $errstr, 30); $request = ""; $request .= "POST /xxx.php HTTP/1.1\r\n"; $request .= "Host: 192.168.0.xxx\r\n"; $request .= "Content-Type: text/plain\r\n"; $request .= "Content-Length: " . strlen($send_data) . "\r\n"; $request .= "\r\n"; $request .= $send_data; $request .= "\r\n"; fputs($fp, $request); while(!feof($fp)) { $response .= fgets($fp, 4096); } fclose($fp);
「HTTP/1.1」→「HTTP/1.0」にするとレスポンスは速いのですが、HTTP/1.1 では遅くなります。
調べてみると、HTTP/1.1 では持続接続機能が追加されたようで、接続が維持された状態になって終了されず遅くなっていたようです。
リクエストヘッダに「Connection: Close」を入れてやると、接続を維持せず終了するとのことです。
以下のように「Connection: Close」を入れると、レスポンスが速くなりました。
$send_data = '送信データ'; $fp = @fsockopen("ssl://192.168.0.xxx", 443, $errno, $errstr, 30); $request = ""; $request .= "POST /xxx.php HTTP/1.1\r\n"; $request .= "Host: 192.168.0.xxx\r\n"; $request .= "Content-Type: text/plain\r\n"; $request .= "Content-Length: " . strlen($send_data) . "\r\n"; $request .= "Connection: Close\r\n"; $request .= "\r\n"; $request .= $send_data; $request .= "\r\n"; fputs($fp, $request); while(!feof($fp)) { $response .= fgets($fp, 4096); } fclose($fp);