2012-05-21
最近の事情
日々 | | ![]()
- 引っ越した
- プロジェクトが変わった
- 等々
毎度のことながら運用保守プロジェクトであります。
アプリ開発っぽい要素はほとんどなくなってしまい、ユーザ問い合わせ対応とバッチ処理の監視・リカバリーが主な作業です。ばかでかいDWHが相手なので全体像の把握が大変。
開発したいっすね
T-SQLのカーソル構文を素で書けますか?
と思ったら書けなかった。普段カーソルなんて使わんし……
set nocount on --カーソルで更新はしません declare c insensitive cursor for select name from sys.tables for read only declare @name varchar(100) open c fetch next from c into @name while @@fetch_status = 0 begin exec ('select ''' + @name + ''' tname, count(*) cnt from ' + @name) fetch next from c into @name end close c deallocate c
なんか地雷踏んだらしい
上のクエリをちょいと書き換えて試していたら「重大なエラーが発生」とか言われてしまった。一応SQL2008R2 SP1(10.50.2500)なので、それなりに最新のはず。
sysスキーマのビュー全部に対してselect countするだけの処理なのですが。
set nocount on declare c insensitive cursor for select name from sys.all_views where schema_id = schema_id('sys') for read only declare @name varchar(100) open c fetch next from c into @name while @@fetch_status = 0 begin exec ('select ''' + @name + ''' tname, count(*) cnt from sys.' + @name) fetch next from c into @name end close c deallocate c
メッセージ 0、レベル 11、状態 0、行 0 現在のコマンドで重大なエラーが発生しました。結果は破棄しなければなりません。 メッセージ 0、レベル 20、状態 0、行 0 現在のコマンドで重大なエラーが発生しました。結果は破棄しなければなりません。
sys.dm_fts_fdhosts
さらなる調査の結果、sys.dm_fts_fdhostsという動的管理ビューに対してselectを行うと問答無用で上記のエラーが発生することが分かりました。
SQL2008SP2(10.0.5500)でも同様でした。
こんな記事もあったけど、手元の環境はSQLEXPRESS/SQLEXPRESSR2というデフォルトです。
割とどうでもいい話でした。
2011-12-23
ローカルな符丁
2chやまとめスレのSSなど読んでいると「」という空のカギ括弧を頻繁に目にする。
文脈から何となく意図は分かるものの、実際のところどうなんだと思ってあるスレで聞いてみた。得られた回答が以下3件。
- 2chでは「……」と同じと考えてよい。何も言えずにいる状態。
- 見たまんま「言葉を失う」とか「絶句」とかいう意味
- 呆然としてるというか、白目剥いたギャグ顔的な反応
言葉を発しようとしたけど出てこなかった、という表現としては確かに秀逸ではある。しかしどこからこんな共通理解が発生したのか? 「……」と同じならなぜ三点リーダーを使用しないのか? どの辺が見たまんまだというのか? ギャグ顔というならいっそ「( ゚д゚)……」と顔文字使ったって良くはないか?
これは批判を意図しているわけではなく。おそらく2ch等の掲示板でネット読者向けに書かれるSSや掌編でしか通じない文法がどのように生じ、共通のお約束として認識されるに至ったのか。そこが興味深い、という話。
ただ、何らかの値が入ることを期待しているフィールドにnullを挿入されるような違和感はあるな。
なお同人小説でこうした表記を見かけたことはまだない。見たことがないだけかも知れないけど。
(そういえば顔文字入れるSSは近年ほとんど見かけないね。今時のスタイルじゃないんだろうか。)
2011-12-22
Silverlightで作るコミケ宅配便搬入札ジェネレータ
技術, Silverlight | | ![]()
まったくもって時宜を逸しているけど、せっかく作ったので公開します。(来年役に立つかもしれないし……)
コミケで宅配便搬入するときは色紙に配送先の情報を書いて箱に貼らないといけません。
毎回札を作るのが著しく面倒なのでついツールを作ってしまいました。合計20時間くらいかかってる気がするので、時間収支としては圧倒的に赤字だけど、まあ勉強も兼ねてるのでいいでしょう。
http://www.isla-plata.org/samples/SLComikeTagGen/SLComikeTagGen.html
使い方は飛び先のページをご覧ください。
処理はクライアント側で全て完結するため、サーバとの通信は一切発生しません。情報漏洩の心配なくお使いいただけます。(リッチクライアントの利点ですな)
Silverlightで適当なアプリを作ってわかったこととか。
技術, Silverlight | | ![]()
やりたいと思ったけどできないことにいろいろぶつかったので、備忘録的にここに記す。
MVVMとか
データアクセスもしないのでコードビハインドにべったり書いてしまったけど、今時のSilverlightのお作法にはまったく従っていない。残念です。
日付の選択支援
コミケの開催日だけ選択できるような仕組みにできればと考えたけど、マスターがどこにもない。開催日が公開されたらいちいちアプリを更新するしかなさそうだ。
依存プロパティとデータバインド
入力部のテキストボックス等の入力に合わせて、荷札部分のテキストブロックを更新させたい。
イベントハンドラを書くのかと思ったら、バインディングを記述するだけで実装できた。すげえ。
Text="{Binding (参照するプロパティ), ElementName=(参照先の部品のID)}"
これだけで勝手に更新されてくれる。
Comboboxの背景色
洗濯されたComboBoxItemの背景色がComboBoxそのものにも反映されるかと思ったんだけど、なんか灰色のグラデーションがかかっているおかげで色が全然目立たない。
グラデーションだけでも解除できればと思ったけど、デフォルトのレイアウトを変更するにはExpression Blendを使う以外に現実的な方法がないらしく、買ってない自分には手も足も出ない。
Comboboxへのデータバインド
バインドする際にComboBoxItemの背景色まで設定させたかったんだけど、どうしてもできなかった。
DataTemplateを持たせて中身にStackPanelを配置し、その背景色をバインドさせることはできたけど、見た目が通常のComboBoxと同じにならないのでダメだった。
結局現状はハードコーディングです。しょぼいのう。
DatePickerのガイド文字列
DatePickerのガイド表示(Watermark)は簡単には変更できない。サブクラス作るしかないんだって。すごい邪魔なんだけど……
http://coelacanth.heteml.jp/site/silverlight/article_10
JSONの扱い
JSON文字列を扱うためにSystem.Jsonという名前空間をusingする。
参照設定どれよ、と思ったらSystem.JsonというDLLがあった。
印刷時の解像度
Silverlightから印刷する際の解像度は96dpiで固定とのこと。この記事を見て初めて知った。
http://msdn.microsoft.com/ja-jp/magazine/hh148152.aspx
http://code.msdn.microsoft.com/10-C-034ee139
というわけで、B6のサイズはタテ128mm*ヨコ182mm。1inch=25.4mmなので、25.4で割って96をかければピクセル数が出る。
元のUIElementの縦横の幅をActualHeight/ActualWidthで取り出し、このピクセル数を割って倍率を出す。この倍率でScaleTransformを使って拡大して印刷すればok。
UIElementを画像ファイルに書き出す
WriteableBitmapクラスを使うと、UIElementをビットマップ型に書き出すことができる。
第2引数にTransformを渡すことで、出力に変形を加えることもできる。
WriteableBitmapをJPEGに変換する方法はこちらを参照した。FluxJpegというライブラリを使用する。
http://d.hatena.ne.jp/ksasao/20100719/1279550667
UIElementのコピー
印刷する際にPrintDocumentにUIElementを渡せば、配下のコントロールごと出力してくれる。
ただ紙幅に合わせてScaleTransformを使って印刷対象のUIElementを拡大してみると、印刷後も画面上で拡大されて見えてしまう。
理想としては、印刷対象のUIElementをコピーしてそれをRenderTransformで拡大し、印刷し終わったら捨てるようにしたい。
でもXAML上のUIElementをコピーする方法がわからない。
WPFならXamlWriterでUIElementのXAML表記を取り出せるけど、Silverlightにはない。
子コントロールと属性を一つずつ手動でコピーする
http://eightyeightpercentnerd.blogspot.com/2008/03/silverlight-cloning-xaml-element.html
リフレクションを使う
どっちも微妙だな!
あきらめて印刷時もWriteableBitmapでビットマップを取り出すようにしたよ。(WriteableBitmapのコンストラクタにtransformを与える場合、元のUIElementは影響を受けない。)
2011-12-12
Group byした検索結果のカウントを取ると行がselectされない?
重複行チェックの処理を書こうとしていたときのこと。
select countで行数を数えるときに、条件がwhereのときとgroup by - havingのときで検索結果が異なるのに気づいた。
結果が0件となるようなwhere句でクエリを書く。
Oracleのdual表には'X'という値を持つ行が1行しかないので、下記の例のクエリは必ず結果0件になる。
select * from dual where dummy = 'Y';
で、countの結果を変数に受ける。
declare cnt number; begin select count(*) into cnt from dual where dummy = 'Y'; end;
このときcntの値は0になる。
declare cnt number; begin select count(*) into cnt from dual group by dummy having dummy = 'Y'; end;
ところがgroup byとhavingで集計結果をカウントする場合、havingに該当する行が存在しないと「ORA-01403: データが見つかりません。」エラーとなる。(dummy='X'としたらcnt=1になる)
行がないからってエラーにしなくてもいいじゃん……わけが分からない……(そもそもなぜhavingの場合はcount=0の行が出てこないのか)
結局こんなコードで回避した。
declare cnt number; begin select count(*) into cnt from ( select count(*) as C from dual group by dummy having dummy = 'Y' ) end;
これでグルーピングした結果の件数を正しくフィルタリングできる。
ところでSQLServerではselect結果が存在しなくてもエラーとならない。
declare @num int set @num = 1 --<<<注目 select @num = COUNT(*) from sys.tables where name='AAA' print @num --(countなしの場合、結果が1行返る) select @num = COUNT(*) from sys.tables group by name having name='AAA' print @num --(countなしの場合、結果が返らない)
いずれのケースでもエラーは出ず、@numの値は0になる。
nvl関数とビューと暗黙の型変換
Oracle | | ![]()
Oracleでビューを書いた。NVL関数でcharのカラム二つをまとめて出力するというもの。
create table tabletest as ( charcolumn1 char(10), charcolumn2 char(10) ); create or replace view viewtest as select nvl(charcolumn1, charcolumn2) charcolumn_nvl from tabletest;
ところがビューをdescするとcharcolumn_nvlの型はvarchar(10)と表示される。引数は両方charなのに……
NVLのレファレンスに答えがあった。
expr1が文字データの場合、Oracle Databaseは2つの引数を比較する前にexpr2をexpr1のデータ型に変換し、expr1のキャラクタ・セットでVARCHAR2を戻します。
http://docs.oracle.com/cd/E16338_01/server.112/b56299/functions119.htm
charで返して欲しいという要望だったので、結局charにcastした。
create or replace view viewtest as select cast(nvl(charcolumn1, charcolumn2) as char(10)) charcolumn_nvl from tabletest;
2011-12-04
Thinkpad X61sを買った
ハード | | ![]()
久しぶりの記事です。
アキバのソフマップでThinkpad X61s(7666-CB1)の中古品が13000円程度で売りに出ていたのでつい衝動買いしてしまった。
CPUはCore2Duo L7300 (1.4Gx2)。ディスク120G。メモリが3Gに増設済みだけど電池なし、OSなし、AC以外の付属品なし。調べたところ電池は互換品が安く出回っているようなので、Linux実験機にするかということ決断した。
ほかにはLet's NoteW7やT7が山のように20000円以下で出ていたけど、こっちはXP時代の今となっては中途半端なスペックだったので眼中に入らず。(たいていメモリが512MBで……)
お試しでWindows7Ultimateを入れて一通りベンチを取った結果がこちら。Webブラウズ等、日常用途にはまったく支障を感じないレベル。
X61s用のバッテリー(互換品)を買った
ハード | | ![]()
さてThinkPadを買ったものの電池がない。なくてもACがあればいいのだけど、なんとなく収まりが悪い。
というわけでこんなのを購入。40Y7001という純正品に対する互換品。ロワジャパン製。3000円もしないので気軽に購入できる。
ThinkPad?X60.X60sの 40Y7001 (SANYOセル)対応バッテリー
- 出版社/メーカー: ロワジャパン
- メディア: エレクトロニクス
- 購入: 2人 クリック: 26回
- この商品を含むブログ (4件) を見る
X61sには付属のスペーサーをねじ止めして使用する。問題なく装着できた。たいした問題ではないけど、電池自体の高さが本体のゴム足よりも高い。(写真参照)
インストールした省電力マネージャでいったん電池のリセットをしてみると、満充電状態で残り時間が1時間半と表示された。ずいぶん少ないな。定格容量31.68Whに対して、満充電容量は29.7Wh。これで外に持ち出して使うのは無理がある。まあ互換品だし。仕方ない。
Windowsのディスクイメージを丸ごとバックアップしてリストアする
技術 | | ![]()
*ご注意:ここに書いてある内容を実行してOSが起動できなくなっても責任は取れませんので、よろしくお願いします。*
さてWindows7がインストールされた状態だけど、これを維持したままでLinuxを入れてみたい。どうするか。
というわけで、500GBのUSB外付けHDDを買ってきた。約4000円。
続いてThinkpadのブートデバイス設定で、USB HDDの優先順位を内蔵HDDよりも上に上げておく。
次にUbuntu11.10のISOイメージをこちらからダウンロード。(Ubuntuにした理由は特にありません)
http://www.ubuntulinux.jp/products/JA-Localized/download
適当なUSBメモリ(1G以上)を用意してから、UNetBootInをダウンロード。(SDカードスロットからはブートできないので、SDを使う際はカードリーダーも準備すること)
http://unetbootin.sourceforge.net/
UnetBootInを実行してから、DiskImageのラジオボタンを選び、ファイル名にダウンロードしたISOファイルをセットする。"Space used to preserve files..."はUSBブート中に保存領域として役立つので、500MBくらいとっておくとよい。
USBメモリのドライブレターを選んでからOKを押すと、ISOイメージがUSB上に起動可能な状態で展開される。
あとはUSBメモリを挿した状態でPCを再起動する。
起動後にメニュー画面が出るので、"Try Ubuntu without installing"を選択。USB上のイメージからUbuntuが起動する。
----
Ubuntuが起動したら、別途購入したUSBHDDを差し込んでみる。無事認識されればファイルマネージャでも見えるはず。ファイルシステム上は/mediaの下に何らかのディレクトリが出てくると思う。自分の場合は/media/SimpleDriveというディレクトリにマウントされた。
左上の白い円のアイコンをクリックし、termと入れるとterminalというアイコンが表示されるので、これを起動。
まずディスクの状態を確認。
%sudo fdisk -l
大体/dev/sdaが内蔵ディスク、/dev/sdbがUSBメモリ、/dev/sdcが外付けディスクになると思う。環境によって異なる場合あり。
続いておもむろに以下のコマンドで内蔵ディスクのダンプを取る。
%sudo dd if=/dev/sda of=/media/SimpleDrive/hdddump.dmp bs=5MB &
出力先のファイル名は適宜変更してください。また外付けドライブ側に内蔵側よりも大きな空き容量が必要。bsパラメータを大きくすれば転送速度が増やせる可能性がある。
あとは黙って待っていればダンプが取れる。途中経過はddのプロセスIDに対して、kill -USR1を送れば表示される。X61sのディスク(120G)のダンプを取るのに3時間くらいかかった。
%ps -ef | grep dd %sudo kill -USR1 *ddのpid*
無事ダンプが取れたら、内蔵ディスクに対してUbuntuを入れるなり何なりご自由に。
その後Windows7に戻したいと思ったときは、またUSBでUbuntuを立ち上げてからterminalで以下のコマンドを実行する。ダンプのin/outを逆にしただけだけど。
%sudo dd if=/media/SimpleDrive/hdddump.dmp of=/dev/sda bs=5MB &
これで内蔵ディスクから起動すればもとのOSが復元される。はず。Thinkpadで試したときは無事できた。
こういうディスクのバックアップ・リストア作業に特化したツールやLinuxディストリもあると思うけど、手間がかけられればタダでできますよという話でした。



FF11するまでは顔文字とかそういうのは全く使わないしわからなかったが、今ではすっかりクセになってます^^;