Hatena::ブログ(Diary)

ushidayの日記 RSSフィード

2011-09-28

Zend Server CE 5.0 for IBM iのdb2_bind_paramで

| 14:01

Zend Server CE 5.0 for IBM i(PHP 5.3 Ver)で、最初からインスコされているIBM_DB2のPECLはバージョン”1.8.4”です。このバージョン”1.8.4”のPECLは、既知のバグがあり、関数、クラス内で「db2_prepare → db2_bind_param → db2_execute」をすると、db2_bind_param関数で割り当てる、変数のスコープがどうもおかしいようで、以下のようなエラーになります。

Warning: db2_execute() [function.db2-execute]: Value Not Bound in hoge.php on line XX
Warning: db2_execute() [function.db2-execute]: Binding Error 3 in 

PECLのサポートサイトより

最新のPECLでは、この既知の問題は解決しているようなので、IBM iのZend Server CEに、2011.09.28現在最新の”1.9.2”を導入しました。

いったんは、IBM i上でビルドを試みましたが、「ibm_db2.so」は出来上がるものの、ファイルのバイト数が明らかに小さく、起動時にエクステンションエラーになってしまいました。結果的にはAIX上でビルドしたエクステンションは、正常通り動作しました。「db2_prepare → db2_bind_param → db2_execute」も問題なく使えます。

もし、バイナリが欲しい方がいたら、このブログにコメント下さい。1.9.2の”ibm_db2.so”を提供します。但し、使用は自己責任で。

ビルドの際に、宣言エラーが抜けている様なので、以下の箇所を追加しました。


-- エラー1
../ibm_db2-1.9.2/ibm_db2.c: In function '_php_db2_connect_helper':
../ibm_db2.c:2109: error: 'conn_handle' has no member named 'c_i5_allow_commit'

-- 対応:「ibm_db2.c」に宣言を追加
   114 long c_i5_allow_commit;

-- エラー2
../ibm_db2-1.9.2/ibm_db2.c: In function '_ibm_db_chaining_flag':
../ibm_db2-1.9.2/ibm_db2.c:6761: error: 'SQL_ATTR_CHAINING_BEGIN' undeclared (first use in this function)

-- 対応:「php_ibm_db2.h」に定数を追加
    302 #ifdef PASE /* i5/OS ease of use turn off/on */
    303     #ifndef SQL_ATTR_CHAINING_BEGIN-
    304         #define SQL_ATTR_CHAINING_BEGIN 2464
    305         #define SQL_ATTR_CHAINING_END 2465
    306         #define SQL_IS_POINTER -4
    307     #endif-
    308 #endif /* PASE */

PECL 1.9.2の確認

f:id:ushiday:20110928122751p:image

とりあえず、この情報が役立つか判らないけど、PECLのサポートに上げておいた。

http://pecl.php.net/bugs/bug.php?id=24382

2011-09-25

FirePHP(Webug)でハマタ。

| 16:00

DBの設定ファイルを「fwrite関数」を使って書き換える、プログラムを実行するとオカシナ動きをした。

hoge.ini」を以下の様にしたかった

  • 実行前の「hoge.ini」
;現在無効な設定1
;現在無効な設定2
現在有効な設定1
  • 実行後の「hoge.ini」
現在無効な設定1
;現在無効な設定2
;現在有効な設定1

でも、こうなっちゃう

;現在無効な設定1
;現在無効な設定2
;現在有効な設定1

処理は、Zend Frameworkを使っているのだけど、アクションコントローラ(Action Controller)のアクションメソッド(Action Method)で「$_SERVER変数」をダンプすると、2回ログが吐き出されている事が分かった。

しかも、2回目のリクエストのHTTPヘッダーには、'HTTP_X_FIREPHP'とか入っている。

原因はコレだ。Chrome Extensionの「Webug(FirePHP)」。恐らくFirefoxのFirePHPも同じだと思う。

Extensionをオフしたら、すんなりOKだった。

DBの追加、更新処理とか2回走ったら、ヤバイねこれ。怖っ!

使わない時は切っておこ。

2011-09-19

DB2 for i copy to DB2 LUW

| 19:18

DB2 for iからDB2 LUWへデータコピーをしたかったので、phpで作った。

処理自体は、簡単なものでスキーマ名とテーブル名をのfrom toを受け取って、DELETE and INSERTするだけ。

CREATE TABLEは既にされているという前提で...

<?php

//Db2 for i
$db2I = Zend_Db::factory($conf);

//SQL
$select = $db2I->select()
              ->from($schema . '.' . $table);
$stmt = $db2I->query($select) ;
$fromRows = $stmt->fetchAll();

//DB2 LUW

$db2LUW = Zend_Db::factory($conf2);

//削除
$count = $db2LUW->delete($schema . '.' . $table);

//追加
foreach ($fromRows as $row ) {
    $db2LUW->insert($schema . '.' . $table, $row);
}

?>

これを、Windows版 Zend Serverで動かすと、DB2 LUWにデータは書かれるのだけど、Zend Server for i上で動かすと、LUW側のコネクションも、IPアドレスやポートは、無視されて、自己参照してしまう。

今回のケースは、たまたまiもLUWもデータベース名、ユーザ、パスワード全てが、両方で同じだったので、自己参照をしたという結果になった。

DB2ドライバが違うんだろうね。確かに接続パラメータも違うしね。

と言うことは、「iの方でDRDA使えば更新出来んじゃね?」と言うことは容易に想像がつくのだが...「'分散データベースの接続の試みで認可が正常に実行されません。 SQLCODE=-30082」であっさり駄目だった。

とりあえず、Windows鯖をかまして、バッチコピーは出来たから良いか。(  ̄σ・・  ̄ )ホジ

DB2トランザクション・ログがフル (SQL0964C)

| 18:25

IBM i上のDB2から、Windows上のDB2 Express Cにデータをコピーする際に、あるテーブルの全レコードを"DELETE"したら、たまたま件数が多かった(12万件程度)のもあって、「SQL0964C データベーストランザクション・ログがいっぱいです。 SQLSTATE=57011」というエラーが返された。

対象法として、

  1. トランザクションを細かくする
  2. ログ容量を増やす

が有る。「1」の方法はコピーを作る上では面倒なので、「2」のログサイズを増やしておいた。増やし方は以下の通り。

    • 「コントロールセンター」を開き、該当するデータベースを右クリック。
    • データベース・ロギングの構成」を選ぶ。
    • 「ロギング・サイズ」の項目で、”1次ログ・ファイルの数”、”2次ログ・ファイルの数”、”各ログ・ファイルのサイズ”のページ数(ページ当たり4K)を増やす。
    • 増やした後は、データベース再起動する。
      • 1次ログ・ファイル(初期値13)・・・データベース起動時に確保される。ログファイル。
      • 2次ログ・ファイル(初期値4?)・・・1次ログで不足した際に、1つずつ確保されるログファイル。
      • ファイルサイズ(初期値1024)・・・ログファイルのページ数(1ページ4K)

2次ファイルを多用するとパフォーマンス的には、1次ファイルより悪い。

db2 get db cfg for <database name> | grep LOG」でコマンドラインでも確認可能

2011-07-21

Zend StudioでZFプロジェクトが作成出来なくなった

| 16:12

ある日、Zend Studioで「Zend Framewrokプロジェクト」を新規作成しても中身が空っぽだった。

コマンドラインから「zf show version」を実行すると以下のスタック

C:\Program Files\Zend\Zend Studio i5 - 7.2.1\plugins\org.zend.php.framework.resource_7.2.0.v20100324-1300\resources\ZendFramework-1\bin>zf show version

Warning: include_once(NetBeansCommandsProvider.php): failed to open stream: No such file or directory in C:\Program Files\Zend\ZendServer\share\ZendFramework\ZendFramework-1.10.6\library\Zend\Loader.php on line 146

Warning: include_once(): Failed opening 'NetBeansCommandsProvider.php' for inclusion ....

「NetBeansCommandsProvider.php」が見つからないと...。はて?そう言えば、NetBeansで、Zend Frameworkプロバイダ登録したのを思い出した。

~/.zf.iniを確かめると以下の通り

php.includepath = "...."
basicloader.classes.0 = "NetBeansCommandsProvider"

あーこれだ。

「NetBeansCommandsProvider」を削除にするか、「%ZEND_STUDIO_HOME%\plugins\org.zend.php.debug.debugger.win32.x86_5.3.7.v20100625\resources\php5\php.ini」の”include_path”に「C:\Program Files\NetBeans\7.0\php\zend」を追加してパスを通すかで対応した。

2011-04-05

SQLRPGプリコンパイラの不思議

11:07

久々に備忘録。

滅多なことでは、SQLRPGを使わないのですが、少しハマったので備忘録を。

例えばこんな感じのD仕様書

D result          DS                  dim(ITEM_Row_Max)               
D                                     LIKEREC(ITEMR :*INPUT)                  

こんな感じのC仕様書だった場合

exec SQL set Result sets Array :result  for :count Rows  ; 

CRTSQLRPGIを実行すると、SQLのプリコンパイルで以下のようなエラー

SQL5011  30     108   桁  60  ホスト構造配列 RESULT が定義されていないか,または使用できない。

LIKERECをEXTNAMEで外部参照しても同じ結果です。


以下は、V5R4 ILE-RPG解説書のLIKERECから引用。

LIKEREC は、2 番目の任意指定パラメーターを使用できます。このパラメーターはレコードのどのフィールドをデータ構造に入れるかを指定します。これには以下のものが含まれます。

    • *ALL 外部レコードのすべてのフィールドが抜き出されます。
    • *INPUT すべての入力可能フィールドが抜き出されます。(これはデフォルトです。)
    • *OUTPUT すべての出力可能フィールドが抜き出されます。
    • *KEY キー・フィールドが、キーがDDS のK 指定に定義されている順番に抜き出されます。


上記によるとデフォルトは「*INPUT」との事。

自分の認識「READ/UPDATE = *INPUT」「WRITE = *OUTPUT」「KLIST = *KEY」*ALLは使わない。

こんな感じです。でも不思議とD仕様書を以下の様に、LIKERECの第二引数を省略するとSQLのプリコンパイルが出きるんですよ。これって何?確かにINPUTもするし、Result SetsでOUTもするけど、その関係で...?でも省略は*INPUTのハズ。どうにも解らない。誰か詳しい人教えて下さい。

D result          DS                  dim(ITEM_Row_Max)               
D                                     LIKEREC(ITEMR)