前回までで、Accessのデータベースを、Windows 2000 Professional上で動くWebObjects 4.5のDirect to Webの機能を利用して、Webブラウザから参照できるところまでを説明した。いろいろ紆余曲折があるが、とにかく参照できるようにはなった。ただ、いきなり世界中から会社のデータベースをのぞかれてしまうというとんでもない状況ではあり、早くログインでパスワードを入れないとダメにしたいところではあるが、カスタマイズは少し先で解説をしたい。 なお、前回、WebObjectsのアプリケーションを起動した直後、検索などがうまく行かないが、何度か検索するうちにうまくいくようになるとお話した。これについては、状況が一定しないので定かではないが、ログインの最初のページで検索を何度繰り替えしてもエラーばかりになるときもある。そのときは、Search、つまりテーブルの各フィールドに対する検索条件が表示されるページに移動し、検索条件は1バイト文字だけで指定して、しかも、containsの検索条件を指定して、何度か検索するとうまく動くようになるようなのだ。釈然としないけど、これでとにかくうまくいくこともある。
では、すでにDirect to Webで作った人は、Newボタンをクリックして新規にレコードを入力したり、一覧の左のアイコンをクリックして、レコード編集にかかっているかもしれない。Accessのデータベースでは、たいがい、オートナンバー型を使って主キーを生成していることが多いとは思うが、その状態では、どうやら新規レコード作成や、レコードの編集ができないのである。ちょっと困ったが、トレースなどをしながら、何とか分かったのは次のようなことだ。Direct to Webの動作に関わることのようなので、その原理から話をしよう。 Accessでは、オートナンバー型のフィールドを設けておけば、確実に主キーとなるので便利だ。レコードの挿入では、その主キーフィールド以外のフィールドに値を指定すればよく、レコード生成時に自動的に新しい値がオートナンバー型のフィールドに入力されるという手軽さがある。だが、Oracleなどを始め、こうした「オートナンバー型」のサポートがされていないデータベースエンジンは多い。サポートされていないというと嘘になるので補足するが、連番を生成するオブジェクトを用意しておき、そこから連番をいただいて、新しいレコードの主キーなどの連番を入れておくフィールドに挿入するという手続きを踏む。テーブル定義と、連番生成は分離しているのだ。 おそらく、WebObjectsはそうした状況を考えているのだろう。連番生成の機能をWebObjects側で用意している。たとえば、あるテーブルAddressがあるとする。その主キーフィールドがidだったとする。そして、レコードの追加や修正を最初に行うとき、データベースにEO_PK_TABLEというテーブルを作る(Enterprize Objects Primary Key Tableの略だろう)。フィールドは2つあって、テーブル名を収めるNAMEフィールド、そのテーブルの主キー値を収めるPKフィールドだ。このPKフィールドは、対応するテーブルの主キーフィールドに設定する「次の値」を記録する。EO_PK_TABLEテーブルを使って、要はテーブルごとに主キーの値に使う連番データを記録するということだ。このとき、Addressテーブルにデータを書き込もうとした場合には、idフィールドと同じ型でPKフィールドを作成する。動作上はもっともな話しなのではあるけども、Accessのテーブルの中では、PKフィールドがオートナンバー型になってしまう。オートナンバー型フィールドは、基本的にはレコード作成時に書き込みがなされそれを変更することはできない。Webブラウザからレコードの追加や修正が行われると、そのEO_PK_TABLEのテーブルに対応したPKフィールドの値を取り出し変更しようとする。つまり、次の値を取り出して、1を加えて元のフィールドに書き戻すのだ。そこで、エラーが出るようなのだ。 また、同様に、WebObjectsが生成した新しいレコードの主キーの値を、この例では、Addressテーブルのidフィールドに入力しようとする。idフィールドがオートナンバー型であるなら、自動的にidフィールドに設定される機能を使う。そのため、外部からidフィールドに書き込みするということをすることは基本的にできない。だけども、Direct to Webで作ったアプリケーションはそれをしてしまうようなのだ。つまり、自分が連番を生成するわけで、オートナンバー型のフィールドにも値を設定しようとしてやはりエラーがでる。Accessが特殊だという話しもあるだろうし、そうしたことはカスタマイズでなんとでもなると言うかも知れないが、とにかく手軽な解決方法が欲しい。
そこで考えたことは、オートナンバー型を使用しないことだ。Addressテーブルにある主キーフィールドのidは、「数値型」にしてしまう。作成したアプリケーションの設定を修正してもいいのだが、Direct to Webという位でアプリケーション作成は素早くできるので、1から作り直した方が早いだろう。また、EO_PK_TABLEがすでに作成されているのであるのなら、Access側を操作して削除しておく方がいい。あるいは、PKフィールドをやはり「数値型」にしておくのでもいいだろう。 こうしておくと、Webブラウザからレコードの追加や修正が基本的にはできるようになる。ただし、一方で、Access側でのアプリケーションを作り込んでいる場合には、要注意だ。オートナンバー型のおかげて、フォームなどで新規レコードを作成時には、主キーフィールドにユニークな値が勝手に入力される。しかしながら、「数値型」にしてしまうと、自分で値を設定しなければならない。EO_PK_TABLEの状態をもとにして、次の主キー値を生成する関数などを作成するのが順当だろうか。Access側で動くアプリケーションを作っている場合にはそちら、そちらの変更が必要になってしまうというわけだ。もっとも、Webで全部やるということになったのであれば、それは問題にはならない。だが、Access側で作り込みをしているのなら、オートナンバーを数値型に変更するのは場合によっては多大な労力がかかる。
いろいろ解析してここまでたどりついたが、実際に住所録で使っているデータベースをWebブラウザから新しいレコードを作成しても、エラーばかりがでる。細かい内容はさておいて、大原則は“SQLステートメントの解釈は厳しい”と思えばよいだろう。Webブラウザで新規レコードを作ってSaveボタンをクリックすると、WebObjectsのアプリケーションはSQL文を生成してそれをODBCに受け渡す。Accessなどを使っているときには、フィールド名などに自動的にクォーテーションを挿入するなどして、極力エラーが出ないように配慮されているが、WebObjectsからではそこまで配慮してくれないようで、結果的にSQLの解釈が厳しくなる。たとえば、どうしてもエラーが出るので、エラーメッセージの中にあるSQL文を、AccessのSQLビューで解析してみたら、SQLのキーワードと同じ名前をフィールド名で使っていた…。また、フィールド名に半角のマイナス記号があってもエラーが出た。「E-Mail」というフィールド名にしていたのだが、このフィールド名をクォーテーションで囲っていなかったので、EというフィールドからMailというフィールドを引き算するといった意味に解釈したのではないかと思う。他にも、AccessではOKだったけど、WebObjects経由だとダメなフィールド名はあるだろう。だが、とにかく、SQLの解釈が厳しいということを念頭に入れて、エラーメッセージを見つめれば原因は分かるかもしれない。 こうして、書き直しなどができるようになったのだけど、それでもダメな場合もあることに気がついた。Accessではテキスト型では「空文字の許可」というプロパティがあり、デフォルトでは「いいえ」になっている。つまり、フィールドには空文字は入力できないのである。SQL的には何も挿入しないか、NULLを入れておけばいいのだが、WebObjects的には、新規作成および更新時にはデータのないフィールドに対してもデータを書いてしまうことがあるようなのだ。ここで、WOTextFieldコンポーネントを使った1行だけのテキストフィールドであれば、それを空欄にすると特に値は指定しない。しかしながら、数行に渡るWOTextコンポーネントを使っている箇所では、そのボックスを空欄にすると、対応するフィールドに、空文字列を代入してしまう。だから、フィールドで空文字列を禁止していたならば、エラーが出るというわけだ。メモ型フィールドはWOTextを使うようなのだが、テキスト型でもある程度以上の長さのフィールドはWOTextを使う。カスタマイズで、WOTextからWOTextFieldに置き換えることで対処は可能だが、もっと手軽にはテーブルの設定で、空文字列を許可してしまうという手段もある。いずれにしても、やっぱりはまってしまうところだろう。
以上のように、WebObjectsのDirect to Webはほんとうに短時間でWebアプリケーションが作成できる。だが、満足に動かすための前提条件があるわけだ。ここでは、Accessのデータベースを使った事例を示したが、おそらく、データベースの種類ごとに同じようにつまずくポイントがあるのではないかと想像できる。ただ、それを知っておくのも今後のことを考えれば重要なことかもしれない。いずれにしても、“Accessのデフォルト”とは相性の悪いところは随所にあると言えるだろう。そこをうまく回避する必要があるわけだ。
【WindowsオフィスでWebObjects】は一段落させてもらう。近々、カスタマイズの方法を中心に、Direct to Webへのさらに突き進めてみたい。 |