■
今日は会社を休んで近所のクリニックで胃の検診を受けました。
生まれて初めてのバリウムで若干緊張。
緊張してまた胃が痛い(;一_一)
朝から絶食、水分取るのもダメというのは
結構きついですね。
たんもつばも飲み込んじゃダメっていうのもつらい。
バリウム検診は結構忙しい。
最初にバリウムを一口飲んで
台に乗ったら上下に動かされ、台の上で仰向けになったり
うつぶせになったり。これは胃壁にバリウムを
満遍なくくっつけるためだそうです。
残りのバリウムを一気に飲んで
いよいよ本番。先生の指示に従って
すばやく体を動かし、息を止める。
仰向けやらうつぶせやら、右斜め45度やその逆など。
自分で動いてても気持ち悪くなります。
診断結果は割りと早く出ました。
結局バリウム検診では怪しいところは見つからず、
ただ胃壁が荒れ気味なので、それが胃痛の原因でしょう、
ということ。
薬を7日分もらって帰りました。
甘いものや味の濃いものは控えてください、と言われて。
これからのクリスマスやら忘年会やらで楽しい時期なんですけどねぇ。
それまでには治しておきたいところです。
今日は家帰ってからバリウムの排出に忙しく、
何も出来ませんでしたわ・・・
■
今日、ヨドバシカメラで15万ぐらい使いました。
暖房器具で5万、ビデオカメラで5万です。
暖房器具はガスファンヒータと電気カーペット。合計5万円。
Edyで払いました。
Edyならヨドバシポイントがそのままつくし、
Edy自体のポイントもつきます。
おまけにチャージのときにもクレジットカードのポイントが。
陸マイラーの常套手段ですね。
ビデオカメラはPanasonicのコレ。
パナソニック デジタルハイビジョン SDビデオカメラ SD5 シルバー 3CCD搭載 HDC-SD5-S
- 出版社/メーカー: パナソニック
- 発売日: 2007/08/25
- メディア: Camera
- 購入: 1人 クリック: 3回
- この商品を含むブログ (3件) を見る
特価で10万3千円でした。
Edyでは5万までしか使えないので、残りはデビットカードで。
Edyカードをもう一枚あれば2枚で決済できるのですが、
めんどくさがりやなのでそこまではしない(^_^;)
ビデオはハイビジョンですが、
今ハイビジョンを買っても見ることができるのは
ハイスペックのパソコンか、ハイビジョン対応のTVだけだそうです。
ちょっと考えましたが、本体の小ささやSDカード記録など、
それ以外の使い勝手を考えて買ってみました。
まあ使い込んでみないと使い勝手はわかりませんけどね。
■
国立国際美術館の現代美術の皮膚展に行ってきました。
NMAO:国立国際美術館
正直、特別展示はがっかりです。
なんか一発芸というか小手先だけのものが多かった。
現代美術は、面白いものは面白いけど、つまらんものは徹底してつまらんです。
むしろ「コレクション3」という所蔵作品の展示のほうが
見ごたえがありました。こっちがあったから今日は救われた感じです。
時代で言えば1960年以降の作品で、古いものも多いですが
今から見るとミッドセンチュリー的な味わいがあっていい。
でもしっかりと骨太でね。安定感がありますよ。
最先端の現代美術も時代を経ればそういう風に感じるものなのでしょうか?
皮膚展で見たものには、芯の太さというか、作品そのものに力がないように思えるのです。
JDBCでバインドできる文字列のサイズの制限→複数のバインド変数を使って解決
以下で紹介されているOracle JDBCのJava.sql.PreparedStatement#setString()の制限について。
[Oracle] JDBCでバインドできる文字列のサイズの制限 | Archive Redo Blog
例えばデータベースキャラクタセットがJA16SJISのDBにvarchar2(4000)の列があったとしても、PreparedStatment#setString()ではUTF-8換算で2000バイトまでしか挿入できない。
UTF-8は日本語が3バイトなので、全て日本語の場合だと666文字までしか入らないという問題があります。
上記のページではsetCharacterStream()を使って解決としていますが、
以下のページではまた別の問題が起きることを指定しています。
http://rryu.sakura.ne.jp/nisenise-fuhito/200402.html
setCharacterStream()を使っている複数の列のうち2つ以上が一定以上、つまり前述の長さ制限よりも長いデータになるとORA-01483: invalid length for DATE or NUMBER bind variableという不可思議なエラーが出るのだ。
いろいろやっているうちにふとエラーになる原因を思いついた。LONG型の列はテーブルにつき1個までしか存在できないという制限がある。そして実のところPreparedStatement#setCharacterStream()はそのLONG型専用のメソッドである。したがってこのメソッドを複数の列に対して使用するとLONG型の列が複数あるという事になるのでエラーになると。一定以下の長さの場合にはエラーにならないのは、おそらくリテラルの限界以下の場合はそのメソッドを使用してもsetString()を使用したのと同じ事になるよう最適化されているのだろう。と、考えれば納得できる挙動だが、エラーメッセージが激しく間違っているのはバグだろうか。
ということで、こんな解決方法を考えてみた。
テーブルHatenaにLongTextというvarchar2(4000)の列があったとして、
これにインサートするSQLを次のように書きます。
insert into Hatena (LongText) values ( ? || ? || ? || ? );
もうお分かりかと思いますが、一列に対するバインド変数を4つに分けて、更新値をそれにあわせて分割するというやり方です。
final String sql = "insert into Hatena (LongText) values ( ? || ? || ? || ? );"; PreparedStatement stmt = conn.prepareStatement(sql); int ix = 0; String[] sqls = {"","","",""}; final String utf8 = "UTF-8"; final String sjis = "Windows-31J"; // 更新値がSJIS換算で4000バイトを超えていないことをチェック if(updateVal.getBytes(sjis).length > 4000){ throw new Exception("値が4000バイトを超えています"); } // SQLがUTF-8で2000バイト以内ならバインド変数一つで十分 if ( sql.getBytes(utf8).length > 2000 ) { /** * SQLがUTF-8で2000バイト以上なら、複数のバインド変数に分けて送信する。 * 分けた後の各部分文字列がUTF-8で2000バイト以内で、 * かつこれらの結合文字列がSJISに変換後4000バイト以内になるようにする。 */ /** * 666文字までなら全て日本語だとしても2000バイトは超えない。 * 従ってこれを分割単位とし、4分割まで行う。 * SJISの4000バイトはUTF-8になると最大6000バイトまで膨らむが、 * 4分割なら666×3×4=7992まで送ることができる。 * (最初にSJISで4000バイトより大きいSQLをはねているので、実際はUTF-8換算で6000バイトが最大) */ final int maxLength = 666; int startIx = 0; int size = sql.length(); for ( int i = 0 ; i < 4 ; i++ ) { if ( size < maxLength ) { sqls[i] = sql.substring(startIx, startIx + size); break; } sqls[i] = sql.substring(startIx, startIx + maxLength); startIx = startIx + maxLength; size -= maxLength; } }else { sqls[0] = sql; } for(int i = 0; i < 4; i++){ stmt.setString(++ix, sqls[i]); } stmt.executeUpdate();
小手先ですが・・・