tag:blogger.com,1999:blog-31154866934888746822024-03-13T20:00:36.566+09:00untitledDuponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.comBlogger91125tag:blogger.com,1999:blog-3115486693488874682.post-53133985347209711372018-01-18T22:30:00.000+09:002018-01-18T22:30:27.054+09:00[デバイス] Windowsのリストアイメージを作るのにZALMANのHDDケースがとても便利<textarea border-style:dotted="border-style:dotted" class="markdown" disabled="disabled"><br />
かなり前から「Windowsのリストアイメージを作る」作業をいっぱいしてるんですが、以前とある人に紹介してもらったデバイスがとても便利でずっと使い続けているので紹介します。 <br />
<a name='more'></a> <b class="w">.</b><br />
### ZALMANのHDDケース<br />
公式サイトはこちら<br />
[ZALMAN - STRAGE/External HDD/SSD Cases](http://www.zalman.co.kr/jp/contents/products/list.html?c=700030)<br />
今回紹介したいのは「ZM-VExxx」シリーズです。<br />
<br />
このシリーズすでに廃盤になったZM-VE300からお世話になってます。<br />
<br />
IODD社からZM-VE400の拡張版なるものも販売されていてこれもAmazonにも並んでいます。両社の関係性はよく知りません。<br />
<br />
<iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=dupont-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B018WUQVY8&linkId=869c6ebc6ea0ce6b59bca82c33ecd8be&bc1=000000<1=_top&fc1=333333&lc1=0066c0&bg1=ffffff&f=ifr"><br />
</iframe><iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=dupont-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B00S3G12E6&linkId=19c0197401c75a23d3cd52be84685b08&bc1=000000<1=_top&fc1=333333&lc1=0066c0&bg1=ffffff&f=ifr"><br />
</iframe><br />
<br />
値段はケースだけです。この中に別途用意した任意の2.5インチのHDDかSSDを入れて使います。<br />
以前はHDDやSSDがセットになっているものも販売されていたんですが、今は見当たりませんね。<br />
<br />
<br />
### 最大の特徴<br />
HDDまたはSSD(以下HDD)の中に起動ディスクをisoファイル化したものを保存しておけば、それを仮想光学ドライブとして認識し起動ディスクにPCを起動させることができるのです。<br />
もちろん外付けHDDとしての機能も併用できます。<br />
<br />
### 使い方(仕様)<br />
0. ケースを開けて(ねじ2本ドライバ同梱)HDDを入れます<br />
0. USBケーブル(USB3.0対応)でWindowsPCに接続します<br />
0. HDDをNTFSでクイックフォーマットします<br />
0. 直下に[_iso]という名前でフォルダを作成します<br />
0. 同フォルダの中に起動ディスクをiso化したファイルを保存します<br />
0. 他PCにUSBで接続し、PCを起動します<br />
0. BootMenuを表示させZALMANの名前のデバイスを選択します<br />
0. isoファイルを光学ドライブとして認識して起動します<br />
<ul><li>_isoフォルダの中には複数のisoファイルを保存しておけます</li>
<li>その場合、デバイスのインターフェイスでisoファイルの切り替えが可能です</li>
</ul></textarea><textarea border-style:dotted="border-style:dotted" class="markdown" disabled="disabled"><br />
### 使い方(運用)<br />
1. WindowsのインストーラーとWindowsPEのisoを保存しておきます<br />
0. WindowsのインストーラーでWindowsをインストールします<br />
0. 必要な設定をSYSPREP直前まで行います<br />
0. WindowsPEで起動します<br />
0. dismコマンドでWindowsイメージを外付けHDDに取得します。「プレマスタ」と呼んでいます<br />
0. SYSPREPコマンドを実行しシャットダウン<br />
0. もう一度WindowsPEで起動してdismコマンドで今度は「マスタ」のイメージを取得します<br />
0. SYSPREPが失敗していたりしてやり直したかったらWindowsPEで起動してdismコマンドで「プレマスタ」をリストアします<br />
</textarea><textarea border-style:dotted="border-style:dotted" class="markdown" disabled="disabled"><br />
+ Ghostイメージで運用することも容易です<br />
+ 複数のイメージファイルを保存しておいてPCの型番や利用者によって任意のイメージを選択したりも可能です(dismコマンドの指定次第)<br />
+ 以前大量のPCをリストアする必要があり、このデバイスを複数購入、WindowsPEのisoとイメージファイルを複製しておいて並べて一斉にリストアするのもやったりしました<br />
+ USB3.0対応なのでネットワーク越しにイメージファイルをダウンロードするよりもはるかに早く処理できます<br />
+ WindowPEで起動させるツールを外付けHDD側に保存しておけば、ツールの更新時にいちいちWindowsPEの作り直さなくて済みます<br />
</textarea><br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com7tag:blogger.com,1999:blog-3115486693488874682.post-39993722650100424292018-01-17T22:30:00.000+09:002018-01-18T00:35:01.586+09:00[WinPE] WindowsPE 10.0.16299.15 (1709相当) を作る時にエラー<textarea border-style:dotted="border-style:dotted" class="markdown" disabled="disabled"><br />
前のエントリで急きょFallCreateorsUpdate相当のWindowsPEを作る必要があった旨書きましたが、その際過去の例を参考に作ろうとしたらエラーになった話。 <br />
この記事では原因は不明のまま回避だけしているので、参考にされる場合は一次的な対応と考えてください。 <br />
また私の環境では発生しましたが、ほかの環境で同様かは不明です。 <br />
<br />
<a name='more'></a> <b class="w">.</b><br />
<br />
### 過去の情報<br />
以前 WindowsPE 10.0.14393.0 を作る時に、Qiitaにある以下の記事に救われて参考にして本当に助かりました。 <br />
[Qiita - Windows 10 用の Windows PE (WinPE) のUSBメモリセットアップ例](https://qiita.com/msakamoto_sf/items/3fff0e7c68e6aaf1a60e) <br />
今回も大部分は上記ページの通りで済んでいるので本当にお世話になります。 <br />
以下の本文では上記ページのディレクトリ配置に準じたコマンドで記載します。 <br />
<br />
<br />
### トラブル内容<br />
WindowsPE 10.0.16299.15を作るためにWADK1709を導入、今回も上記記事の通りにコマンドを流してみたら、途中からエラーが発生してしまいます。<br />
エラーの内容は以下のようなものです。<br />
<div class="border" style="background-color:#000000; color:#FFFFFF;">WinPE-Dot3Svc-Package: The specified image is no longer serviceable and may be corrupted.<br />
Discard the modified image and start again.<br />
Error: 0x80073713<br />
<br />
エラー: 14099<br />
<br />
The specified image is no longer serviceable and may be corrupted.<br />
Discard the modified image and start again.<br />
<br />
DISM ログ ファイルは C:\Windows\Logs\DISM\dism.log にあります<br />
<br />
(中略)<br />
<br />
WinPE-WMI-Package: The specified image is no longer serviceable and may be corrupted.<br />
Discard the modified image and start again.<br />
Error: 0x800f0830<br />
<br />
エラー: 0x800f0830<br />
<br />
DISM が失敗しました。操作は実行されませんでした。<br />
詳細については、ログ ファイルを確認してください。<br />
<br />
DISM ログ ファイルは C:\Windows\Logs\DISM\dism.log にあります<br />
</div>(ログファイルを覗いてみたんですが、私には理解できる内容ではありませんでした。)<br />
<br />
### エラー回避方法<br />
エラーが発生したら/discardして一旦マウントを外しましょう。 <br />
<div class="border" style="background-color:#000000; color:#FFFFFF;">Dism /Unmount-Image /mountdir:"C:\WinPE_amd64\mount" /discard</div>しかる後にWinPE_amd64フォルダを削除して作り直しです。 <br />
<br />
さて、この問題は以下のコマンド以降で発生します。 <br />
<div class="border" style="background-color:#000000; color:#FFFFFF;">Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\ja-jp\WinPE-Dot3Svc_ja-jp.cab"</div>一度エラーになると、以降の行のコマンドがすべてエラーになります。 <br />
<br />
`WinPE-Dot3Svc_ja-jp.cab` のファイルがないのかと思って対象のディレクトリを見てみるとファイル自体は存在しています。 <br />
で、 WinPE-Dot3Svc とはなんなのか調べてみると「有線ネットワークでの IEEE 802.X 認証プロトコルのサポート」だそうです。 <br />
[参考] [Hardware Dev Center - WinPE: パッケージの追加 (オプション コンポーネント リファレンス)](https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn938382%28v=vs.85%29.aspx) <br />
幸い私の業務ではその要求はないので、この読み込みをスキップします。行の先頭に「: 」をつけるだけでもよいでしょう。<br />
<br />
<br />
### 関係ないけど<br />
前に [Stackeditで書いてBloggerに投げてみた](http://dupont-kedama.blogspot.jp/2014/10/stackeditblogger.html) って記事を書いてみたんですが、Publish機能が本当に公開になってしまうんで、ラベルつけたりもできずタイトル変えるとほかの投稿になっちゃうし、ちょっと使いづらいところがあって。 <br />
なので今回から以下の記事の方法に変えました。 <br />
[Qiita - BloggerでMarkdown書けるようにした。](https://qiita.com/her0m31/items/1804bdc251a647e0e9a8) <br />
サックリ書けていい感じです。<br />
<br />
StackEditはオンラインMarkdownエディタとしてはとても優秀だと思いますよ。 <br />
私の使い方に合ってなかっただけで。<br />
<br />
</textarea><br />
<b class="w">.</b><br />
<br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-89819770746190811282018-01-16T23:00:00.000+09:002018-01-17T20:22:52.519+09:00[WinPE] WindowsPEで画面の解像度が低いのをなんとかしようと四苦八苦した話<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blog.Entry.001</title> <link rel="stylesheet" href="https://stackedit.io/style.css" /> </head> <body class="stackedit"> <div class="stackedit__html"><p><strong>実に約3年3か月ぶりのエントリ投稿です。</strong></p><p>WindowsPEでWindowsイメージファイルからリストアするためのツールをHTAで作っていたんですが、最近購入したPCでWindowsPEの画面の解像度がどうにも低くて、HTAの画面も見づらくて、これでは困ると思い解像度を上げるための四苦八苦を記録しました。 少し遠回りをしてしまったので結論だけ知りたい方が一番下の「結論」の見出しまでどうぞ。</p><a name='more'></a><br />
<h2 id="windowspeでの解像度をあげる">WindowsPEでの解像度をあげる</h2><h3 id="デバイスドライバの追加">デバイスドライバの追加</h3><p>解像度が低い理由について、まずは「ビデオアダプタのドライバーが足りない」のだと考えます。<br />
WindowsPEを作る時にデバイスドライバを追加する方法があるのは知っていたので、前にWindowsPEを作った環境(WADK)を引っ張り出してWindowsPEを作る準備をします。<br />
今回の機種はEPSONのNA512EなのでEPSONダイレクトのWebサイトからWindows10向けのvideoドライバをダウンロードしてきます。<br />
MSのサイト <a href="https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn938381(v=vs.85).aspx">[Microsoft] Hardware Dev Center - WinPE: ドライバーの追加</a> を見ると、サンプルの構文は<code>Dism /Add-Driver /Image:"C:\WinPE_amd64\mount" /Driver:"C:\SampleDriver\driver.inf"</code> となっています。<br />
これ以上の説明が探しても見つからず、NA512Eのvideoドライバを解凍してみても「driver.inf」というファイル名は見当たりません。<br />
きっといずれかのinfファイルがその機能を果たすのだろうと推測し、 <code>na512e_video_21_20_16_4627_w10\VGA\win64\Graphics\igdlh64.INF</code> を指定してみました。<br />
<code>Dism /Add-Driver /Image:"C:\WinPE_amd64\mount" /Driver:"C:\winpe_source\WinPE_amd64\Drivers\na512e_video\Graphics\igdlh64.INF"</code> こんな感じです。<br />
エラーにならず成功したのでこれでよかったのだろうと考えていますが、結果的にこれで<strong>解像度はあがらなかった</strong>のでよかったのかどうか正確にはわかりません。</p><h3 id="応答ファイルで解像度を指定してみる">応答ファイルで解像度を指定してみる</h3><p>さらに調べてみると、WindowsPEの起動初期化時に解像度を指定できるらしいことがわかりました。</p><ul><li><a href="https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn938394(v=vs.85).aspx">[Microsoft] Hardware Dev Center - Wpeinit と Startnet.cmd: WinPE スタートアップ スクリプトの使用</a></li>
<li><a href="https://docs.microsoft.com/ja-jp/windows-hardware/customize/desktop/unattend/microsoft-windows-setup-display">[Microsoft] Hardware Dev Center - microsoft-windows-setup|Display</a></li>
<li><a href="https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn621892.aspx">[Microsoft] Hardware Dev Center - Windows 展開サンプル応答ファイル</a></li>
</ul><p>上記のWADKの「Windows システムイメージマネージャー」を使って応答ファイルを作り、解像度を指定してみます。<br />
ツールでは複数の機種に対応させておきたいのでNA512Eの最高解像度1980x1240ではなく、ウチではデスクトップは17インチスクエアディスプレイが主流なので1280x1024を指定してみます。<br />
もちろんNA512Eのグラフィックも対応している解像度です。<br />
結果として<strong>解像度は変わらず</strong>、wpeinitのログに解像度変更失敗のWarningログ<code>can't change screen resolution</code>が残っています。</p><p>ほら、そろそろ辛くなってきましたよ。</p><h3 id="そもそもuefiモードでは解像度を変更できない">そもそもUEFIモードでは解像度を変更できない?</h3><p>検索していたらこんなQAがヒットしました。<br />
<a href="https://social.technet.microsoft.com/Forums/windows/en-US/b5c08612-9461-426b-ab35-97377ef2e09f/how-can-i-change-the-resolution-of-winpe?forum=w8itproinstall">TechNet - How can I change the resolution of WinPE?</a><br />
<code>If you are booting in UEFI mode, you cannot change the resolution.</code><br />
「UEFIモードで起動している場合は解像度変更できねーよ」と・・・なんということでしょう。応答ファイルを作ったのは完全に無駄でした。</p><p>そう考えると思い当たる節が。前まではWindows7プリインストールまたはWindows10のWindows7ダウングレードプリインストールのPCだけ扱っていました。<br />
この場合UEFI対応のハードであっても出荷時にUEFI=disableにされてBIOS互換で起動します。<br />
今回のNA512EはWindows10プリインストールで購入しており、出荷時設定はUEFI=enableです。<br />
つまりハードウェアの違いというよりUEFI設定の違いにより解像度が違うのだと考えられました。</p><p>ただ、「UEFIモードの場合は自動で適当な解像度になる」ということらしいのですが、それにしては解像度が低すぎます。800x600にも満たないんじゃないかというレベルです。</p><h2 id="不具合だったらしい">不具合だったらしい</h2><h3 id="もっと早く教えてよ">もっと早く教えてよ</h3><p>Google先生はすごいですね。うっかり以下のようなページを見つけてしまいました。<br />
<a href="https://support.lenovo.com/jp/ja/solutions/ht503599">Lenovo - Microsoft Windows PE ADK 1607を使用した Windows 10のインストールで、デフォルトの解像度が落ちる – ThinkPad</a><br />
<code>UFD (USB Flash Drive)で起動し、セキュアブートが有効の場合、Microsoft Windows 10 PE ADK 1607 のインストールすると、解像度が編集されます。解像度は 640x480 に落ちます。</code><br />
<code>この問題は、Microsoft Windows PE 10 ビルド 1607の不具合です。</code><br />
確かにWindowsPEを作っている環境はWindows10バージョン1607だしWADKも1607です。<br />
(Lenovo以外のページが見当たらないんだけど)これだったのか・・・</p><h3 id="ここでまた罠に引っかかる">ここでまた罠に引っかかる</h3><p>じゃー早速新しいバージョンのWADKを使ってみよう。ということで、見てみると最新版はWADK 1709らしい。<br />
<a href="https://developer.microsoft.com/ja-jp/windows/hardware/windows-assessment-deployment-kit">[Microsoft] Hardware Dev Center - Windows アセスメント & デプロイメント キット (Windows ADK)</a><br />
ダウンロードして上書きインストールしてみようと思ったら前のバージョンをアンインストールせよと。アンインストールしてからインストールを仕掛けるとなにやらダウンロードが始まりました。<br />
かなり時間がかかりそうだったので放置してスクリーンロックがかかりましたので解除して進捗を見ようと思ったら「ようこそ」でくるくるしたままロック解除できない。<br />
EscもCtrl+Alt+Delも電源ボタン(短く押す)も反応しません。<br />
思い切って電源長押しで強制終了して起動してみると、今度は「更新プログラムを構成しています。100%完了 コンピューターの電源を切らないでください」のくるくる表示のまま終わりません。<br />
やっと終わったと思ったら再起動するたびに「Windowsの準備をしています コンピューターの電源を切らないでください」くるくる表示で毎回待たされるようになってしまいました。<br />
あかんやつや。</p><p>「Windows ADK for Windows 10 Version 1709」の説明には特に書いてないんだけど、「Windows 10 バージョン 1703 用 Windows ADK」の説明には「このバージョンの Windows ADK および Version 1703 用の Windows 10 IoT Core ADK アドオンには、Windows 10 Version 1703 が必要です。」って書いてあります。<br />
ということはWADKのシステム要件もWindows10 1709だったんではないのかな?<br />
でもそういうことはさ、インストールが始まる前に教えてくれるもんじゃないの?</p><p>とりあえずこの環境は捨てて、改めてWindows10バージョン1709(10.0.16299.15)の環境を作り、WADK 1709をインストールしてWindowsPE 10.0.16299.15 を作り直しました。<br />
結果、<strong>やっと無事適当な解像度に落ち着いてくれました。</strong></p><h3 id="結論">結論</h3><ul><li>WindowsPE 10.0.14393.0(1607相当) はUEFIモードで起動すると解像度が異常に低くなることがあるよ</li>
<li>WADKは適切なビルドバージョンのOSに入れましょう</li>
</ul></div></body> </html> Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-63363179933980890202014-10-24T02:30:00.001+09:002014-10-24T03:43:28.212+09:00Stackeditで書いてBloggerに投げてみた<p>実に半年ぶりのエントリ。</p>
<h4 id="マイブーム">マイブーム</h4>
<p>マイブームって死語っぽいですね。</p>
<p>最近仕事でめっさメモとか記録とかをガリガリ書いていて、少しでも楽しようと思っていたら今更Markdownに目覚めました。</p>
<p>で、Bloggerの投稿もMarkdownでできたらいいのにと思ってみて検索したら最初に見つけたのがこの方法です。 <br>
<a href="http://tizio1976.blogspot.jp/2013/11/chrome-stackedit-markdown-blogger.html">Chrome アプリ StackEdit を使い Markdown で作成そして Blogger へ投稿</a> <br>
(もう一年前の記事ですね。)</p>
<a name='more'></a>
<h4 id="stackedit">StackEdit</h4>
<p>とりあえず<a href="https://chrome.google.com/webstore/detail/stackedit/iiooodelglhkcpgbajoejffhijaclcdg/related">StackEdit</a>入れてみたんですが、なんか綺麗な作りで気に入りました。</p>
<h3 id="拡張">拡張</h3>
<p>拡張はたぶん<a href="https://help.github.com/articles/github-flavored-markdown/">GFM</a>と同等です。</p>
<table>
<thead>
<tr>
<th>表組みも</th>
<th>こんな風に</th>
<th>書けます</th>
</tr>
</thead>
<tbody><tr>
<td>ほらね</td>
<td>マジこれ</td>
<td>便利ですよね</td>
</tr>
<tr>
<td>これ考えた人</td>
<td>天才</td>
<td>に認定します(何様</td>
</tr>
</tbody></table>
<p>StackEdit上はシンタックスハイライトも使えるんですが、Blogger上に反映させるには <br>
別途 google-code-prettify か highlight.js の読み込みが必要です。 <br>
今回は面倒なので省略。</p>
<h3 id="ちょっと違うところ">ちょっと違うところ</h3>
<p>私の知ってるMarkdownと違うのは強制改行。Space*2がなくても改行表示になります。 <br>
どっちがいいかって言われると悩ましいところですね。 <br>
Markdownのコンセプトは理解しているつもりだし、強制改行のマークはあった方がよいと思うんですが、それがSpace*2ってのは正直あまりしっくり来てない。</p>
<h4 id="更新">更新</h4>
<p>Bloggerに投げた後もそのリンクが保たれているので、編集した結果を上書きで更新することができます。これも便利。 <br>
拡張に対応しているのでほとんどMarkdownだけで記事が書けるはず。 <br>
本当にどうしても必要なところだけhtmlタグを書けばいいし。(<!– more –> とかね。)</p>
<p>ちなみにこの記事の本文はBloggerのエディタを一切使わずに書きました。</p>
<p>まだちょっとわかってないのがラベル。 <br>
StackEditから再publishするとBlogger上で付与したラベルが消えてしまうんで、これはちょっと調べてみます。</p>
<h4 id="リンク">リンク</h4>
<p>Markdownでどうしようもないのがリンクのtarget属性。 <br>
html的にもあまりごちゃごちゃ指定すべきでない(利用者が選ぶべき)みたいな話は聞いたことがあるんですが、やはり他サイトへのリンクは半ば強制的に別ウィンドウまたは別タブで開いてほしいと思うわけです。 <br>
ということでテンプレートに「他サイトへのリンクはtarget=’_blank’になる」ようなJavaScriptを仕込みました。(今度アイコンも付与するよう検討します。)</p>
<p>せっかくMarkdownで書いているんですから<code><a href='hogehoge' target='_blank'>ふがふが</a></code>とかいちいち書いていられません。</p>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-45715110569771865922014-04-16T18:00:00.000+09:002014-04-17T03:13:33.389+09:00[Oracle] 複数の異なるバージョンのOracleサーバーを扱う場合の注意点例えば社内に複数の異なるバージョンのOracleサーバーがある場合の注意点をチラ裏的にメモします。<br />
<br />
実は答えはここにあります。<br />
<a href="http://www.oracle.com/jp/system-requirement/interoperability-support-195844-ja.html" target="_blank">Oracle Client/Server Interoperability Support 現在の互換性に関するサポート状況(2013/08/01)</a><br />
<br />
具体的な注意点としては以下の2点を挙げておきます。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="http://3.bp.blogspot.com/-gV7nHc2F6x0/U07H8yP8J2I/AAAAAAAAAoU/aShXIEXFBx8/s1600/lan_cable.jpg" /></div><h2>注意点1 クライアント(ドライバ)バージョンの選択の話</h2>集計業務や分析業務などのために複数のサーバーに接続する場合、ありますよね。<br />
例えば私の環境の場合は、サーバーは Oracle9i 9.2とOracle11g 11.2 と Oracle12c 12.1 が混雑し、かつ一つのPCからどれにも接続する必要があったのですが、そんな時に上のリンク先のマトリクス図を見る必要があって、このいずれにも接続できるクライアントのバージョンは 11.1 または 11.2 であることが分かります。(この場合は11.2の方がBetterですね。)<br />
<br />
<br />
<h2>注意点2 DBLINKが作れない話</h2>もう一つこの話で結構悩ましいのが、データベースリンク(以下DBLINK)です。<br />
サポートされないバージョン間で「CREATE DATABASE LINK」をすると、構文自体は通るのですが、作られたリンクテーブルを実際に参照しようとすると<br />
<div class="comment caution">ORA-03134: このバージョンのサーバーへの接続は、サポートされていません</div>というエラーが出ます。<br />
<br />
ウチではOracle12cのサーバーからOracle9iのサーバーへDBLINKを作れないことでバージョン間マイグレーションやデータ連携などで結構困りました。<br />
<br />
サポートに聞いてみたところ、直接DBLINK作るのは無理との回答でしたが、一つの解決策として<br />
<div class="comment">Oracle12c → Oracle11g → Oracle9i という風に間にブリッジのようなサーバーを挟むと作れる。</div>と教えてもらいました。<br />
<br />
うーん、アクロバティック(°∀° )<br />
<br />
残念ながらウチの場合は自由に使えるOracle11gがなかったのでコレは試してません。Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-29176170525463306902014-03-03T17:00:00.000+09:002014-03-03T17:00:03.091+09:00PowerShellで「mysql.exeで外部SQLファイルを引数に使う」方法 の補足少し前「<a target="_blank" href="http://dupont-kedama.blogspot.jp/2014/02/powershellmysqlexesql.html">PowerShellで「mysql.exeで外部SQLファイルを引数に使う」方法</a>」という記事を書き、大反響(アクセス数合計15くらい)をいただいております。<br />
需要のなさがよくわかる数値ですね。ありがとうございます。<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
pre.powershell {
background-color:#444499;
color:#FFFFFF;
margin: 0.2px 10px;
padding-left: 1em;
}
</style><br />
さて、その中で紹介した構文<br />
<pre class="powershell">PS >Get-Content .\hogehoge.sql | mysql -u myuser -p</pre>ですが、この外部ファイルにマルチバイト文字を使っている場合、そのままでは文字化けることが判明したので補足エントリです。<br />
<br />
<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<br />
答えから先に書くと、仮にこの外部ファイルがUTF-8で書かれている場合、以下のように書き直す必要があります。<br />
<pre class="powershell">PS >$OutputEncoding = [text.encoding]::GetEncoding('UTF-8')
PS >Get-Content .\hogehoge.sql -Encoding 'UTF8' | mysql -umyuser -p
</pre><br />
ここでのポイントは二つ<br />
<br />
<h3>読み取る際の文字コード</h3>Get-Content ~ -Encoding 'UTF8'<br />
でファイルから読み取る際の文字コードを指定します。<br />
<br />
これをしないと文字化けした状態で読み取られ、文字化けしたまま引き渡されるので、<br />
検索にヒットしなかったり、文字化けした文字列が挿入されたり、途中で構文エラー等で失敗したりします。<br />
<br />
<br />
<h3>引き渡す際の文字コード</h3>$OutputEncoding = [text.encoding]::GetEncoding('UTF-8')<br />
でアウトプット(=mysql.exeに渡す)の文字コードを指定します。<br />
<br />
これをしないと文字化けして引き渡されるので、<br />
検索にヒットしなかったり、文字化けした文字列が挿入されたり、途中で構文エラー等で失敗したりします。<br />
当然引き渡す前に指定しておく必要があるので先に書きます。<br />
<br />
<br />
<h3>UTF8? UTF-8?</h3>Get-Contentの-Encodeオプションの引数指定は '<b>UTF8</b>'<br />
[text.encoding]::GetEncoding()の引数指定は '<b>UTF-8</b>'<br />
とそれぞれ書式が違いますが、それぞれこの通りに書かないとエラーになります。<br />
うん、しんだらいいよ。<br />
<br />
<br />
<h3>もっと詳しい話</h3>すごい人がこんな記事を書いてくれています。<br />
(参考)クラシック コマンドと PowerShell の間のエンコード設定<br />
<a target="_blank" href="http://d.hatena.ne.jp/ladybug/touch/20111203">http://d.hatena.ne.jp/ladybug/touch/20111203</a><br />
<div class="comment"><i>引用:</i>PowerShell ではコマンド間の入出力はオブジェクトのストリームになりました。これは、PowerShell とクラシックなコンソール コマンドの間ではオブジェクトとバイナリの間のマーシャリングが必要になるということです。また、PowerShell はコンソール コマンドとのデータのやりとりを文字列ベースで行おうと努力します。</div>概念が理解できてない私には、なんか、すごい、難しいです。<br />
想像では.NET Frameworkの仕様にも関係してるんじゃないかと思ったりするんですが、むつかしいことはよくわかりません。<br />
<br />
<br />
<h3>私なら</h3>パイプで引き渡すメリットとしては元の文字コードから別の文字コードに変換できたり、文字列加工をできることでしょうか。<br />
私なら気持ち悪いのでやりたくないです。<br />
<br />
「俺は文字コードと戦いたいんじゃない。mysqlを使いたいだけなんだ。」という方は、前回も紹介した mysql.exe の --execute オプションと sourceコマンドを合わせた以下の書式がよいと思います。<br />
<pre class="powershell">PS >mysql -umyuser -p -e"source .\hogehoge.sql"</pre>これならPowerShellのコンソールが外部ファイルを読みに行くことはなく、世界に平和が訪れます。<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com1tag:blogger.com,1999:blog-3115486693488874682.post-41774526734085503782014-02-21T18:00:00.000+09:002014-02-21T18:00:12.723+09:00[PHP]Smarty3.1にバージョンアップして困ったこと その4ウチではPHPのテンプレートライブラリ(テンプレートエンジン)であるSmartyを使ってるんですが、昨年最新版の3.1系にバージョンアップしたら色々困ったことが起きたのでその記録の続きです。<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<br />
<div class="comment" style="padding: 20px;">include_pathに置いているtplファイルを読んでくれない。</div><br />
共通化したアプリケーションのtplファイルとか例外表示用のtplとかをPHPのinclude_pathに置いていたんですが、これを表示してくれなくなりました。<br />
template_dir以外を読み込むときにいろいろ制約ができたみたいです。<br />
<br />
詳しくは以下のマニュアルページを参照ください。<br />
<br />
ファイルテンプレートリソース<br />
<a target="_blank" href="http://smarty.m-takagi.org/resources.html">http://smarty.m-takagi.org/resources.html</a><br />
<br />
$use_include_pathプロパティ<br />
<a target="_blank" href="http://smarty.m-takagi.org/variable.use.include.path.html">http://smarty.m-takagi.org/variable.use.include.path.html</a><br />
(このページは翻訳されていません)<br />
<br />
tplファイルやpluginをinclude_pathに置く場合は<br />
$Smarty->use_include_path = true;<br />
をしておく必要があります。<br />
<br />
<br />
今回の連載は一応ここまでにします。<br />
<br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-64064794478773930832014-02-20T18:00:00.000+09:002014-02-20T18:00:01.861+09:00[PHP]Smarty3.1にバージョンアップして困ったこと その3ウチではPHPのテンプレートライブラリ(テンプレートエンジン)であるSmartyを使ってるんですが、昨年最新版の3.1系にバージョンアップしたら色々困ったことが起きたのでその記録の続きです。<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<br />
<div class="comment" style="padding: 20px;">プラグインディレクトリを追加しようとして怒られる。</div><br />
<br />
参照させるプラグインディレクトリを追加するために<br />
<pre class="border" style="background-color: #EFEFAF;">$Smarty->plugins_dir[] = './plugins';</pre>とかやってたら<br />
<div class="comment caution">Notice: Indirect modification of overloaded property Smarty::$plugins_dir has no effect</div>って怒られる。<br />
つまり$plugins_dirプロパティはマジックメソッド__get() によって返される値になったということ。<br />
その変数への参照がないので変更ができません。<br />
<br />
探してみると同じようなことでやられたひとがごろごろ出てくる。<br />
(例えば)<br />
<a href="http://blog.still-laughin.com/archives/2011/11/smarty_31.html">http://blog.still-laughin.com/archives/2011/11/smarty_31.html</a><br />
<br />
Smarty3.1から2系以前の記法で動かなくなったって話で、<br />
setPluginsDir()とかaddPluginsDir()を使いなさいってことでした。<br />
<br />
<br />
3.1以降での書き方はこう<br />
<pre class="border" style="background-color: #EFEFAF;">$smarty->addPluginsDir(
array(
'dir1/plugins/',
'dir2/plugins/',
)
);</pre>または<br />
<pre class="border" style="background-color: #EFEFAF;">$smarty->setPluginsDir(
array(
$smarty->plugins_dir[0],
'dir/plugins/',
)
);
</pre><br />
addPluginsDir()の場合は追加したものが後ろにつくので、意図的に走査する順番を変えたいなら<br />
setPluginsDir()でセットしなおした方がよいでしょう。<br />
<br />
マニュアルを見るとわかるのですが、この記法はPluginディレクトリ以外も同様です。<br />
以下ディレクトリ関係のメソッドです。<br />
<dl><dt>get</dt>
<dd>getCacheDir()</dd> <dd>getCompileDir()</dd> <dd>getConfigDir()</dd> <dd>getPluginsDir()</dd> <dd>getTemplateDir()</dd>
<dt>set</dt>
<dd>setCacheDir()</dd> <dd>setCompileDir()</dd> <dd>setConfigDir()</dd> <dd>setPluginsDir()</dd> <dd>setTemplateDir()</dd>
<dt>add</dt>
<dd>addConfigDir()</dd> <dd>addPluginsDir()</dd> <dd>addTemplateDir()</dd> </dl>(add~は複数指定可能なディレクトリのみのメソッドです。)<br />
<br />
<br />
まだ続く予定です。<br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-62482134276694123062014-02-19T18:00:00.000+09:002014-02-19T18:00:00.092+09:00[PHP]Smarty3.1にバージョンアップして困ったこと その2ウチではPHPのテンプレートライブラリ(テンプレートエンジン)であるSmartyを使ってるんですが、昨年最新版の3.1系にバージョンアップしたら色々困ったことが起きたのでその記録の続きです。<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<br />
<br />
<div class="comment" style="padding: 20px;">エラーハンドラがfiletime()やunlink()実行時のエラーを拾ってしまう。</div><br />
他にも困ってる人がいました。<br />
<a target="_blank" href="http://k-holy.hatenablog.com/entry/2012/05/10/212139">http://k-holy.hatenablog.com/entry/2012/05/10/212139</a><br />
<br />
file_exists()等でファイルの存在確認をせずに@filetime()したり@unlink()したりしているせいで、独自のエラーハンドラーが拾ってしまう罠でした。<br />
<br />
で、Smarty3.1のソースをいろいろ見てみると、<br />
Smarty.class.phpの<br />
Smarty->muteExpectedErrors()<br />
のところに、以下のコメントがありました。<br />
Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include<br />
- @filemtime() is almost twice as fast as using an additional file_exists()<br />
- between file_exists() and filemtime() a possible race condition is opened,<br />
which does not exist using the simple @filemtime() approach.<br />
<br />
<br />
うーん。<br />
実際には1ファイルあたり0.01秒とかなんで別に気にしないんだけどなー。<br />
それくらいは覚悟してSmarty使ってるつもりだし。<br />
ちなみに3.0.9のソースの同じ個所では、ちゃんとfile_exists()で分岐してました。<br />
<br />
Smartyのlibs配下のファイルを編集するのはもちろんやめた方がいいので、<br />
Smartyを使う場合は独自のエラーハンドラーを使うのをやめる。<br />
どうしても使う場合は<br />
display()とかfetch()の前に$Smarty->muteExpectedErrors()後に$Smarty->unmuteExpectedErrors()を入れるようにする。<br />
とかで回避できます。<br />
が、どちらにしても、個人的にはあまり好きな書き方ではなく、ちょっと残念な気持ちになります。<br />
<br />
<br />
まだ続く予定です。<br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-34936260134380156222014-02-18T18:00:00.000+09:002014-02-19T13:57:03.236+09:00[PHP]Smarty3.1にバージョンアップして困ったこと その1ウチではPHPのテンプレートライブラリ(テンプレートエンジン)であるSmartyを使ってるんですが、昨年最新版の3.1系にバージョンアップしたら色々困ったことが起きたのでその記録です。<br />
ちなみにSmarty2との後方互換を維持するためのSmartyBCクラスっていうのもあるんですが、今回は3.0と3.1の違いを中心に紹介するので触れません。<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<br />
<br />
<div class="comment" style="padding: 20px;">公式サイトの日本語マニュアルが実は古い。</div><br />
Smartyの公式のマニュアルは公式サイトの以下のURLにあります。<br />
<a target="_blank" href="http://www.smarty.net/documentation">http://www.smarty.net/documentation</a><br />
<br />
この公式サイトのSmarty3のマニュアルは英語は更新日が2013-06-28となっていて3.1系に対応しているのですが、<br />
日本語のものは更新日が2011-01-10で、これは3.0系のままです<br />
なので、3.1系の新しいメソッドなどが載っていません。<br />
<br />
新しいメソッドが追加されているだけなら古いマニュアルのままでもそれほど困ることはないのですが、Smarty3.0→3.1には互換性のない仕様変更があり、ハマります。<br />
(詳しくは後日別エントリで紹介します。)<br />
<br />
これについては英語のマニュアルを見るしかないと思われ、それは英語力が貧弱な私には悩まし・・・かったんですが、<br />
なんとなく探していたら高木正弘さんのサイト <a target="_blank" href="http://www.m-takagi.org/">http://www.m-takagi.org/</a> に日本語訳がありました。<br />
<a target="_blank" href="http://smarty.m-takagi.org/">http://smarty.m-takagi.org/</a><br />
すばらしい。<br />
<br />
<br />
まだ続きます。Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-3320572807427021072014-02-17T17:00:00.000+09:002014-02-17T17:00:07.194+09:00PowerShellで「mysql.exeで外部SQLファイルを引数に使う」方法Windowsでmysqlクライアント(mysql.exe)を使う場合、何も考えなければコマンドプロンプト(cmd.exe)のCUIから利用するのが一般的でした。<br />
時代も変わり、WindowsServer2008以降はPowerShellが標準のCUIに取って代わろうとしています。<br />
PowerShellのCUIでもmysql.exeはほぼ同様に利用できますが、SQL文を外部ファイルから利用した場合に少し取り扱いが変わります。<br />
<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h3>入力のリダイレクト</h3>コマンドプロンプトの時はこのように書いていました。<br />
<pre class="border" style="background-color:#000000; color:#FFFFFF;">mysql -u myuser -p < C:\batch\hogehoge.sql</pre>
ところがこれをPowerShellのCUIで入力すると、
<pre class="border" style="background-color:#444499; color:#FF9999;">発生場所 行:1 文字:20
+ mysql -u myuser -p < C:\batch\hogehoge.sql
+ ~
演算子 '<' は、今後の使用のために予約されています。
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RedirectionNotSupported</pre>
と怒られます。<br>
今後っていつだよ。
出力のリダイレクト'>'は使えるのにね。
<br><br>
<h3>パイプで渡す</h3>最初に思いついたのはこれでした。
PowerShellからの構文で書けるPowerShellらしい書き方です。
<pre class="border" style="background-color:#444499; color:#FFFFFF;">PS >Get-Content C:\batch\hogehoge.sql | mysql -u myuser -p</pre>Get-Contet(略式gc)でテキストの内容を取得してパイプで後述に渡します。
<br><br>
これで期待通りの動作はするのですが、mysql.exeからの出力を受け取る方法がちょっと違い、枠線が表示されません。<br>
枠線が表示されないのは外部ファイルだからではなく、パイプで渡した場合の仕様のようです。<br>
例えば「SHOW STATUS LIKE 'TABLE%';」をした場合はこうなります。<br>
<pre class="border" style="background-color:#444499; color:#FFFFFF;">PS >"SHOW STATUS LIKE 'TABLE%';" | mysql -u myuser -p
Enter password:******
Variable_name Value
Table_locks_immediate 493
Table_locks_waited 0
Table_open_cache_hits 0
Table_open_cache_misses 0
Table_open_cache_overflows 0</pre><br><br>
<h3>sourceコマンド</h3>もう一つの案はこちら。
mysql.exeの--execute(略式-e)オプションとMySQLのsourceコマンドを利用する方法です。
<pre class="border" style="background-color:#444499; color:#FFFFFF;">PS >mysql -u myuser -p -e "source C:\batch\hogehoge.sql"</pre>これはコマンドプロンプトでも全く同じ書き方で動作します。
<br><br>
また、-eオプションの場合は標準出力に枠線が表示されます。
<pre class="border" style="background-color:#444499; color:#FFFFFF;">PS >mysql -u myuser -p -e "SHOW STATUS LIKE 'TABLE%';"
Enter password:******
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Table_locks_immediate | 493 |
| Table_locks_waited | 0 |
| Table_open_cache_hits | 0 |
| Table_open_cache_misses | 0 |
| Table_open_cache_overflows | 0 |
+----------------------------+-------+</pre><br>
ちなみにこの結果を一度変数に入れてから表示させるとこうなります。
<pre class="border" style="background-color:#444499; color:#FFFFFF;">PS >$result = mysql -u myuser -p -e "SHOW STATUS LIKE 'TABLE%';"
Enter password:******
PS >$result
Variable_name Value
Table_locks_immediate 493
Table_locks_waited 0
Table_open_cache_hits 0
Table_open_cache_misses 0
Table_open_cache_overflows 0</pre>あれ既視感。
<br><br><br>
<b>まとめ</b>
外部ファイルにする場合の多くはバッチで実行するので結果など見ないでしょうし、更新のみのSQL文ならどちらでも同じなので、どちらでも構わないと思います。<br />
好きなほうを使いましょう。Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-18160342142693726172013-10-30T17:00:00.000+09:002013-10-30T17:00:15.763+09:00[TOSDI] MySQLのBIGINT符号なしをStringで扱う理由Talend Open Studio for Data Integration関連エントリです。<br />
今回はMySQLのBIGINT UNSIGNED(符号なし)の型のカラムを取得する際に数値型ではなく文字列型で扱う理由についての考察です。<br />
併せてDATETIME(6)などのマイクロ秒を含む日付時刻型についての注意事項も記述します。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
文中の「TOSDI」は「Talend Open Studio for Data Integration」を略して記述したものです。<br />
文中の「BIGINT符号なし」は「BIGINT UNSIGNED」と同等です。<br />
<br />
<br />
<h2>標準の動き</h2>前回も少し触れましたが、スキーマ定義の際、BIGINT(符号あり)の場合はLong(数値型)ですが、BIGINT符号なしの列はStringクラスがプリセットされます。<br />
<img class="img" src="http://4.bp.blogspot.com/-6TgXZZJrz0Q/UnACVikARxI/AAAAAAAAAn0/DZwAMXch2GQ/s1600/bigint.png" /><br />
結論から言うと、TOSDIにとある制限事項があり、その制限の中でこの挙動は妥当な挙動と言えます。<br />
<br />
<h2>選択可能なJavaのデータ型</h2>上記画像の画面でGUIにより以下の中から選択して変更することができます。<br />
<ul><li>Boolean</li>
<li>Byte</li>
<li>byte[]</li>
<li>Character</li>
<li>Date</li>
<li>Double</li>
<li>Float</li>
<li>BigDecimal</li>
<li>Integer</li>
<li>Long</li>
<li>Object</li>
<li>Short</li>
<li>String</li>
<li>List</li>
</ul><br />
<br />
<h2>設定</h2>この挙動は設定ファイルによりマッピングされたもの(正確にはマッピングされなかったもの)です。<br />
具体的な設定の見方を記載すると長くなるので別の機会にしますが、簡単に言うと以下の通りです。<br />
<p style="padding-left: 10px;">各データ型に対してどのクラスをプリセットするかが設定ファイルに書かれています。<br />
ここで定義しなかった場合、デフォルトのクラスがプリセットされます。<br />
デフォルトのクラスは標準ではStringになっています。</p>そして、BIGINTはLongにマッピングされ、BIGINT符号なしは未定義になっています。<br />
この設定ファイルを編集すればデフォルトを変更することもできますが、このファイルでわざわざBIGINT符号なしが未定義→Stringになっているのには理由があり、以下私の推測を交えて記載します。<br />
<br />
<br />
<h2>理由1 Longに収まらない</h2>(PHP以外で)アプリケーション開発をされている方はすでにお気づきかもしれませんが、BIGINT符号なしが格納できる数値の最大値はかなり大きく、JavaのLong型では収まりません。<br />
<br />
<b>Javaの数値型(整数型)の最小最大値</b><br />
<table class="border"><tr><th>型名</th><th>最小値</th><th>最大値</th></tr>
<tr><td>Short</td><td style="text-align:right;">-32768</td><td style="text-align:right;">32767</td></tr>
<tr><td>Integer</td><td style="text-align:right;">-2147483648</td><td style="text-align:right;">2147483647</td></tr>
<tr><td>Long</td><td style="text-align:right;">-9223372036854775808</td><td style="text-align:right;">9223372036854775807</td></tr>
<tr><td>BigInteger</td><td colspan="2" style="text-align:center;">事実上制限なし</td></tr>
</table><br />
<b>MySQLの数値型(整数型)の最小最大値</b><br />
<table class="border"><tr><th>型名</th><th>最小値</th><th>最大値</th></tr>
<tr><td>SMALLINT</td><td style="text-align:right;">-32768</td><td style="text-align:right;">32767</td></tr>
<tr><td>SMALLINT UNSIGNED</td><td style="text-align:right;">0</td><td style="text-align:right;">65535</td></tr>
<tr><td>MEDIUMINT</td><td style="text-align:right;">-8388608</td><td style="text-align:right;">8388607</td></tr>
<tr><td>MEDIUMINT UNSIGNED</td><td style="text-align:right;">0</td><td style="text-align:right;">16777215</td></tr>
<tr><td>INT</td><td style="text-align:right;">-2147483648</td><td style="text-align:right;">2147483647</td></tr>
<tr><td>INT UNSIGNED</td><td style="text-align:right;">0</td><td style="text-align:right;">4294967295</td></tr>
<tr><td>BIGINT</td><td style="text-align:right;">-9223372036854775808</td><td style="text-align:right;">9223372036854775807</td></tr>
<tr><td>BIGINT UNSIGNED</td><td style="text-align:right;">0</td><td style="text-align:right;">18446744073709551615</td></tr>
</table>(TINYINTは省略)<br />
MySQL Integer Types (Exact Value): <a target="_blank" href="http://dev.mysql.com/doc/refman/5.6/en/integer-types.html">http://dev.mysql.com/doc/refman/5.6/en/integer-types.html</a><br />
<br />
<div class="comment">実際に試してみましたが、スキーマ定義でBIGINT符号なしをLongに設定した場合、超える数値を取得したときに、明らかにオーバーしていれば例外が発生しますが、微妙なところだと丸められて誤った数値で取り扱われてしまうことがありました。<br />
(Longで収まるかの判定をするときに計算を誤ってしまうためなんでしょうか。Java詳しくないのでよくわかりません。)</div><br />
<h2>理由2 BigIntegerが使えない</h2>Longより大きな数値を扱えるJavaのクラスはjava.math.BigIntegerなのですが、TOSDIで選択できる型は先に列挙したとおりで、残念ながらこれを選ぶことができません。<br />
java.math.BigDecimalが選択できるのに。惜しい仕様ですね。これは使えるようにしてもいいと思うんですが。<br />
(確実に9223372036854775807を超えないとわかっている場合のみLongに入れるという方法もありますが、私はそういうのは避けるべきと考えています。)<br />
<br />
<h2>解決方法</h2>そこで、どんな数値(の文字列)も確実に受け取れるのがStringというわけです。<br />
<br />
<h2>Stringにした場合の課題と対応方法</h2>Stringにしてしまうと困るのが四則演算ができなくなることです。<br />
なので、加工の過程で数値として演算する場合は、別途java.math.BigIntegerをimportして、これに変換し、加工し、出力する必要があります。<br />
(具体的な方法はここでは省略しますが、いずれ記事にしたいとは思います。)<br />
また、MySQLから取り出すSQL文で加工し、演算が必要ない値にしてからStringに取り出すというのも選択肢の一つです。<br />
<br />
<br />
<h3>マイクロ秒</h3>これも前回触れた話ですが、MySQL5.6.4からDATETIME型にマイクロ秒まで格納できるようになりました。<br />
これを取り扱うには注意が必要です。<br />
<br />
<h2>Javaの仕様</h2>Javaの言語で扱える日付時刻はミリ秒までです。<br />
Java Date: <a target="_blank" href="http://docs.oracle.com/javase/jp/6/api/java/util/Date.html">http://docs.oracle.com/javase/jp/6/api/java/util/Date.html</a><br />
(ナノ秒を取得するメソッドがあるみたいですが、これは現在時刻のみのようです)<br />
ミリ秒よりも細かい精度の時刻をDate型で定義するとミリ秒に丸められてしまいます。<br />
精度を維持するためにはこの場合もStringで受け取るしかありません。<br />
<br />
また、マイクロ秒の時刻の演算は言語の仕様によりできません。<br />
分解して計算するのも不可能ではないかもしれませんが、正直そんな構文見たくありません。<br />
どうしても演算が必要な場合はSQL文で計算してからStringで取り出すのが妥当かなと思います。<br />
<br />
<h2>注意点</h2>注意しなければならないのは、DATETIME(6)のように定義した列もTOSDIはDATETIME()だと認識することです。<br />
(TOSDI ver5.3.0で動作確認)<br />
なのでデフォルトでは前回説明したとおり、Date型がプリセットされます。<br />
これは手動で確実にStringに変更する必要があります。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-90148982872456518792013-10-28T17:00:00.000+09:002013-10-29T03:07:34.285+09:00[TOSDI] 日付時刻型のカラムを扱う場合のポイントTalend Open Studio for Data Integration関連エントリです。<br />
今回は日付時刻型のカラムを含むテーブルのデータを取得する際の注意についてです。<br />
主にMySQLとの関係について説明しています。他RDBMSについては各仕様に置き換えてお考えください。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
文中の「TOSDI」は「Talend Open Studio for Data Integration」を略して記述したものです。<br />
<br />
<h2>標準の動き</h2>TOSDIで日付型や日付時刻型の列を含むテーブルをリポジトリに登録する際、RDBMSやデータ型の細かい違いを問わずデフォルトでは「日付パターン」が「"dd-MM-yyyy"」になっています。<br />
<img class="img" src="http://4.bp.blogspot.com/-af329uiAmsQ/Um1JIwnxzKI/AAAAAAAAAnQ/7BTwicgyTxc/s1600/%E6%97%A5%E4%BB%98%E6%99%82%E5%88%BB%E5%9E%8B%E3%81%AA%E3%81%AE%E3%81%AB%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88ddMMyyyy.png" /><br />
<div class="comment">TOSDIではテーブルから取得した各値(属性値)をDB上の列定義から最適なJavaの型(クラス)の変数に格納しようとします。<br />
上の画像では左から5列目の「Type」の欄は取得後にJavaで扱う際の型になります。これはこの画面で手動で変更できます。<br />
Javaの"Date"は日付時刻を扱うクラスで、ミリ秒まで格納できる精度を持ちます。<br />
<a target="_blank" href="http://docs.oracle.com/javase/jp/6/api/java/util/Date.html">http://docs.oracle.com/javase/jp/6/api/java/util/Date.html</a><br />
「日付パターン」はこのクラスから値を取り出して表示する際やSQL文を生成する際に使用されます。<br />
(なお、上の画像で、「BIGINT UNSIGNED」のフィールドを"String"クラスに格納しようとする理由については次回解説する予定です。)<br />
</div><br />
<h2>挿入可能なパターン</h2>これをこのまま別のテーブルの日付型の列に挿入しようとした場合、"dd-MM-yyyy"のパターンの文字列で挿入しようとします。<br />
これを受け入れられるRDBMSならばよいのですが、すくなくともMySQLでは無効です。<br />
SQLモード次第で、エラーとなるか、すべて"0000-00-00"で挿入されてしまいます。<br />
(MySQLの)DATE型であれば、"yyyy-MM-dd"などに変更する必要があります。<br />
<div class="comment">MySQLで日付型(DATE型)の列へのINSERT時に受け入れられる文字列は"yyyy-MM-dd"か"yy-MM-dd"です。<br />
(区切り文字は半角記号ならほとんどの文字を受け入れる。区切り文字ナシも可。)<br />
<a target="_blank" href="http://dev.mysql.com/doc/refman/5.6/en/date-and-time-types.html">http://dev.mysql.com/doc/refman/5.6/en/date-and-time-types.html</a></div><br />
<h2>時刻情報の損失</h2>取得する元のカラムが日付時刻型で時刻まで格納している場合、時刻の部分が失われます。<br />
MySQLのDATETIME型やTIMESTAMP型(やOracleのDATE型)の場合は時刻まで格納されている可能性があるので、秒までの時刻を取得できる日付パターンに変更すべきです。<br />
この場合、"yyyy-MM-dd HH:mm:ss"となります。<br />
<br />
<h2>日付パターンの選択</h2>なお、TOSDIのGUIでは、日付パターンの列にカーソルを合わせてCtrl+Spaceでいくつかのパターンから選択できるようになります。<br />
<img class="img" src="http://4.bp.blogspot.com/-7UhnJNgZ_AA/Um1MdA2NmiI/AAAAAAAAAnk/j8FyjF2w_Jg/s1600/screen7.png" /><br />
"yyyy-MM-dd HH:mm:ss"が選択肢にないのですが、MySQLの場合、"yyyy-MM-dd'T'HH:mm:ss"でも問題ありません。<br />
(選択肢に"yyyy-MM-dd"がないのが謎です。)<br />
<div class="comment">"yyyy-MM-dd'T'HH:mm:ss"の"T"は実際に「T」という半角英字で、この書式はISO8601の定義に基づいているものと思われます。<br />
MySQLのマニュアルでは特に説明されていませんが、エラーにならず挿入可能です。「T」以外の(記号ではない)文字は挿入時にエラーになります。<br />
またISO8601のサブセットにあたるRFC3339で定義されている"Z"をつけ"yyyy-MM-dd'T'HH:mm:ss'Z'"にすると挿入時にエラーになります。(例:2013-10-28T11:51:45Z)<br />
<br />
ISO8601:<a target="_blank" href="http://ja.wikipedia.org/wiki/ISO_8601">http://ja.wikipedia.org/wiki/ISO_8601</a><br />
RFC3339:<a target="_blank" href="http://suika.fam.cx/~wakaba/wiki/sw/n/RFC%203339">http://suika.fam.cx/~wakaba/wiki/sw/n/RFC%203339</a><br />
W3CDTF:<a target="_blank" href="http://www.w3.org/TR/NOTE-datetime">http://www.w3.org/TR/NOTE-datetime</a> (参考)<br />
MySQL5.6 DATETIME:<a target="_blank" href="http://dev.mysql.com/doc/refman/5.6/en/datetime.html">http://dev.mysql.com/doc/refman/5.6/en/datetime.html</a><br />
<br />
なお、MySQL5.6.4以降でDATETIMEにミリ秒まで格納している先進的なあなたは"yyyy-MM-dd'T'HH:mm:ss.SSS"で取り出してください。<br />
ただし、マイクロ秒まで格納している場合、つまりDATETIME(6)などfsp(fractional seconds part)を4以上にしている場合は、JavaのDateクラスの制限によりこの方法では取り出せません。<br />
これについての具体的なテクニックは次回紹介したいと思います。<br />
</div><br />
<br />
<h2>デフォルトの挙動変更について</h2>なお、この日付パターンのデフォルトをアプリで設定できたらと思うんですが、残念ながらその機能はありません。<br />
数年前から要望は上がっているのですが、実装はされていません。<br />
<a target="_blank" href="https://jira.talendforge.org/browse/TDI-5927">https://jira.talendforge.org/browse/TDI-5927</a><br />
<br />
各RDBMSの各データ型ごとに最適な日付パターンがプリセットされているのがよいと思うんですけどね。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-44090833202085984782013-10-11T18:00:00.000+09:002013-10-29T03:07:23.215+09:00[TOSDI] DB接続情報の保持方法についての注意事項Talend Open Studio for Data Integration関連エントリです。<br />
今回はデータベース接続のユーザー名パスワードの保持方法についてです。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>結論</h2>から先にいうと、ユーザー名やパスワードは暗号化されないので注意してね。ってことです。<br />
<br />
<h2>DB接続</h2>例えば少し前に紹介した <a target="_blank" href="http://dupont-kedama.blogspot.com/2013/09/tosditalend-open-studio-for-data_24.html">[TOSDI]Talend Open Studio for Data Integration その2</a> の中で、MySQLのサーバーに接続しています。<br />
入力インターフェイスではユーザー名は見えてますが、パスワードは黒丸で表示されるためその画面では見えません。(文字数がバレてますけど)<br />
<img class="img" src="http://2.bp.blogspot.com/-dfxwwI2fRdA/UlbSTyETQ8I/AAAAAAAAAm4/m7PmSsf60BU/s1600/screen5.png" /><br />
<br />
<h2>コードビュー</h2>ですが、ジョブを作成してこの接続を利用すると、コードビューの画面では生テキストで表示されます。<br />
<img class="img" src="http://4.bp.blogspot.com/-Jh9Gc2EUHcQ/UlbPkNi5f3I/AAAAAAAAAms/wbPaNy3jaRI/s1600/screen4.png" /><br />
これはエクスポートしたジョブパッケージも同様で、テキストファイルに書き込まれています。<br />
<br />
<h2>つまり</h2>必要な人(パスワードを知られてもよい人)にしかこのアプリケーション及びエクスポートしたジョブパッケージに触れさせないようにしましょう。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-41224018380237360262013-10-07T17:00:00.000+09:002013-10-29T03:07:12.387+09:00[TOSDI] Talend Open Studio 関連サイトTalend Open Studio for Data Integration関連エントリです。<br />
今回はTalend Open Studioの関連サイトの紹介です。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
紹介するサイトの半数以上は英語のサイトになります。<br />
<br />
<br />
<h2>公式サイト</h2><br />
<b>Talend.com (英語)</b><br />
<a href="http://www.talend.com/" target="_blank">http://www.talend.com/</a><br />
公式サイト<br />
<br />
<b>Talend株式会社 (日本語)</b><br />
<a href="http://jp.talend.com/" target="_blank">http://jp.talend.com/</a><br />
公式サイトの日本語訳(兼日本法人サイト)<br />
<br />
<b>TalendForge Tutrials (英語)</b><br />
<a href="http://www.talendforge.org/tutorials/menu.php" target="_blank">http://www.talendforge.org/tutorials/menu.php</a><br />
公式チュートリアルサイト<br />
(ちなみにIE8では参照が困難。別のブラウザが必要。)<br />
<br />
<b>Talend Forum (英語)</b><br />
<a href="http://www.talendforge.org/forum/" target="_blank">http://www.talendforge.org/forum/</a><br />
公式掲示板サイト<br />
<br />
<b>Talend Help Center (英語)</b><br />
<a href="https://help.talend.com/display/HOME/Welcome" target="_blank">https://help.talend.com/display/HOME/Welcome</a><br />
Knowledgebaseが充実(アカウント登録要)<br />
<br />
<b>Talend Busiess Community (日本語)</b><br />
<a href="https://www.talend-bc.jp/" target="_blank">https://www.talend-bc.jp/</a><br />
Talendの公式パートナー会社によるの日本コミュニティサイト <br />
<br />
<br />
<br />
<h2>個人/有志サイト</h2><br />
<b>Talendのススメ (日本語)</b><br />
<a href="http://talend-jp.jinaka.com/index.html" target="_blank">http://talend-jp.jinaka.com/index.html</a><br />
更新時期 2012年<br />
サブドメインまで作られているが、志半ばで更新が止まってしまっている。<br />
<br />
<b>komlog (Tag:Talend) (日本語)</b><br />
<a href="http://komlog2.blog.so-net.ne.jp/tag/articles/Talend" target="_blank">http://komlog2.blog.so-net.ne.jp/tag/articles/Talend</a><br />
更新時期 2010年~2013年<br />
Talend関連のエントリがいくつか。<br />
<br />
<b>Talend by Example (英語)</b><br />
<a href="http://www.talendbyexample.com/" target="_blank">http://www.talendbyexample.com/</a><br />
各パーツの解説がある。<br />
<br />
<br />
Talend社はもともとフランスの会社で、もしかしたらフランス語のサイトですばらしいものがあるかもしれないのですが、少なくとも私は(英語でもかなり残念なのに)フランス語が全く無理なので探していません。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-84559483564797426382013-10-04T17:00:00.000+09:002014-05-22T03:02:31.567+09:00[TOSDI] 無償版でジョブスケジューリングTalend Open Studio for Data Integration関連エントリです。<br />
今回はジョブをスケジュールする方法について説明します。<br />
関連して作成したジョブを他のPCで実行する方法も触れます。<br />
<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
「Talend Open Studio for Data Integration」が長いので以下では「TOSDI」と略します。<br />
<br />
<h2>無償版にはスケジューリング機能がない</h2>公式サイトの比較を見ると、Talend Enterprise Data Integration(有償版)にはスケジューリングの機能がありますが、Talend Open Studio for Data Integration(無償版)にはありません。<br />
<img class="img" src="http://1.bp.blogspot.com/-7sIQ-dmFOrw/UkxYpKmsA8I/AAAAAAAAAmI/4K1BLU5iTyY/s600/%E6%AF%94%E8%BC%83.png" /><br />
<p style="text-align: right;"><i>(Talend公式サイト <a href="http://jp.talend.com/products/data-integration" target="_blank">http://jp.talend.com/products/data-integration</a> より引用)</i></p><br />
(有償版は使ったことがないのでどんな風にスケジュールできるのかは知りません。)<br />
ただ、ETLツールなんて基本的にはバッチで動かすのが前提でしょうから、スケジュールできないとお話になりません。<br />
そこで無償版でジョブを無人稼動させる方法を紹介します。<br />
<br />
<h2>手順</h2>TOSDIでは作成したジョブをエクスポートすることができます。<br />
<img class="img" src="http://1.bp.blogspot.com/-gBVAm8a3rCg/UkxYo6m-B-I/AAAAAAAAAl8/xKuytL714qs/s600/screen2.png" /><br />
<br />
エクスポートするとzipファイルひとつにまとめられ、このzipファイルを伸張すると中にbatファイルとshファイルがあります。<br />
<img class="img" src="http://2.bp.blogspot.com/-d4VI_E9DjAk/UkxYpK-8BLI/AAAAAAAAAmA/LeIMuQC1Td8/s600/screen3.png" /><br />
<br />
そう、あとはご想像の通り、Windowsならbatファイルをタスクスケジューラーに、Unix/Linux/Macならshファイルをcronで設定すればよいということです。<br />
タスクスケジューラーやcronが気に食わなければ他のスケジューラーをご利用ください。<br />
<br />
<h2>ジョブの持ち出し</h2>このエクスポートしたzipパッケージはそのまま他のPC(またはサーバー)に持ち出して実行させることができます。<br />
持ち出し先にJavaの実行環境が必要ですが、TOSDIのインストールは不要です。<br />
この持ち出しを前提とすると、スケジューリングに関しては有償版と無償版の優劣がなくなります。<br />
<br />
<h2>実行ログ</h2>バッチ処理となるとやはり実行ログは必須ですよね。<br />
TOSDIではロギングについて複数の方法/機能があります。<br />
すべてをここで説明するのは難しいのでひとつだけ紹介すると、前回のエントリで「標準出力」の話をしました。<br />
実行時にこの標準出力をパイプしてテキストファイルか何かに渡せばそのまま記録されます。<br />
(行すべてを出力したりしたらパフォーマンス的にもディスク容量的にもセキュリティ的にも面倒なことになるのでご注意ください。)<br />
<br />
より詳細なログの取得方法は別途研究しているので後日記事にします。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-54979196512058926632013-10-03T17:00:00.000+09:002013-10-29T03:06:43.823+09:00[TOSDI] インストーラーダウンロードの怪Talend Open Studio for Data Integration関連エントリです。<br />
今回はインストーラーのダウンロードについて小ネタです。<br />
この記事の内容はこの記事を書いた2013/10/03時点での情報です。<br />
<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>どっちだよ?</h2>Talendの公式サイトからインストーラーをダウンロードするためにダウンロードページを開くと、こんな感じです。<br />
<img class="img" src="http://2.bp.blogspot.com/-Me02GRee8gE/UkxhH8NAQsI/AAAAAAAAAmc/x0CALTYMHc8/s1600/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%A9%E3%83%BC.png" /><br />
Talend公式サイト ダウンロードページ <a href="http://jp.talend.com/download/data-integration" target="_blank">http://jp.talend.com/download/data-integration</a><br />
<br />
左右どちらも名前が同じで、OSのアイコンがちょっと違っていますが、Mac以外の人は正直どっちを選べばよいのかわかりません。<br />
OSアイコンにマウスカーソルを合わせてみても何もアドバイスしてくれないし、クリックしても反応ありません。<br />
ペンギンや旗のマークが片側に2つあったりする理由もさっぱりです。<br />
ちなみにこれは日本語サイトでも英語サイトでも同じです。<br />
<br />
<h2>答え</h2>「DownloadNow!」ボタンのリンク先を見るとそれぞれ<br />
左:http://talend.dreamhosters.com/tos/release/V5.3.1/TOS_DI-r104014-V5.3.1.zip<br />
右:http://talend.dreamhosters.com/tos/release/V5.3.1/TOS_DI-Win32-r104014-V5.3.1.exe<br />
となっています。<br />
<br />
つまり、左側は64bit版、右側は32bitWindows版でした。<br />
インストールするOSにあわせてお選びください。<br />
<br />
実際このことで困るのは64bit版のWindowsを使っている人だけで、それ以外の人はダウンロードまたはインストールの過程で気づくはずですね。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-29356880912694251022013-09-24T17:00:00.000+09:002013-10-29T03:06:05.332+09:00[TOSDI]Talend Open Studio for Data Integration その2前回はTalend Open Studio for Data Integration(以下TOSDI)がどんなアプリケーションであるかの概要を紹介させていただきました。<br />
簡単におさらいすると、「EclipseベースのGUIを備えたJavaで動く無償のETLツール」です。<br />
<br />
今回は「基本的な操作がいかに簡単か」を紹介したいと思っています。<br />
<img border="0" src="http://3.bp.blogspot.com/-xjnRV5k67yU/Uj3ooc3QUII/AAAAAAAAAlU/Y7iz2GQQH8U/s1600/%E3%81%BE%E3%81%A3%E3%81%9F%E3%81%8F%E7%B0%A1%E5%8D%98%E3%81%A0.jpg" /><br />
<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>インストール</h2>インストールも非常に簡単で、ウィザードに従っていればできてしまいます。<br />
インストール直後からほぼ作業に入れると思ってください。<br />
<br />
<br />
<h2>画面構成</h2>ジョブを作る画面はこんな感じです。<br />
<img border="0" src="http://1.bp.blogspot.com/-8ZMRgZX-aQM/Uj32WlF5NvI/AAAAAAAAAls/sufanAF8Adw/s1600/screen1.png" class="img" /><br />
<br />
左側のペインはリポジトリ。メタデータや保存されたジョブデータが格納されます。<br />
中央上段はジョブを編集するための作業スペース、その右側のパレットは各種空パーツの引き出しです。<br />
その下段はジョブ、コンポーネントのプロパティを編集したり実行、デバッグなどを行うための機能が集結しています。<br />
<br />
<h2>今回の流れ</h2>RDBMSからデータを取得してRDBMSにデータを入れるというのを試します。<br />
流れを見ていただくだけなのでデータソースとロード先は同じサーバー同じデータベース内の別のテーブルにします。<br />
またシンプルにお見せするため、今回は加工せずにそのままのデータをロードします。<br />
よってテーブル構造はデータソースとロード先で同じです。<br />
本来であれば「Oracleから取得してMySQLに入れる」というようなことをやれればよかったのですが、操作方法が伝わればよいと思いMySQLだけにしました。<br />
<br />
なお、動画はHDになっていますが、一本一本が短いのでHDに切り替わる前に終わってしまうかも。<br />
文字とかが見づらい場合はHDに変わってから最大化して再生しなおしてください。<br />
<br />
<h2>DBConnectionを作る</h2>Metadataの中にMySQLのサーバーへの接続情報を保存します。<br />
といってもウィザードに従ってサーバー名、ユーザー名、パスワード、デフォルトスキーマを入力するだけです。<br />
なお、ここの接続は特に言及がないかぎりJDBC接続になり、JDBCドライバはすでに入っているのでダウンロードしてくる必要はありません。<br />
<iframe width="640" height="480" src="//www.youtube.com/embed/prpVIErnsdw?rel=0" frameborder="0" allowfullscreen></iframe><br />
<h4>ここで操作している内容</h4><ol><li>「DB Connections」を右クリックして「Create Connection」を選択します。</li>
<li>任意の名前をつけて次へ進みます。(本来は「Purpose(目的)」や「Description(説明)」を適切に入力してください。)</li>
<li>「DB Type」で接続する先のDBMS種別を選択します。</li>
<li>ログイン名、パスワード、サーバー名、Schemaなどを入力すると、接続文字列が生成されます。</li>
<li>一通り入力したら「チェック」でテスト接続して「成功しました」が出るのを確認します。</li>
</ol><br />
<br />
<h2>Schemaを取得する</h2>DBに接続できたら今度はテーブル定義などを引っ張りだします。<br />
ここはマウスの操作だけで完結できます。<br />
このツールで使う予定のないテーブルに関しては取得する必要がありません。<br />
<iframe width="640" height="480" src="//www.youtube.com/embed/IPTnVY-ou0Y?rel=0" frameborder="0" allowfullscreen></iframe><br />
<h4>ここで操作している内容</h4><ol><li>作成したConnectionを右クリックして「スキーマ情報の取得」を選択します。</li>
<li>ここではフィルタなしで次へ進んでいます。接続先にテーブルが大量にあるとわかっている場合はフィルタを使いましょう。</li>
<li>スキーマの下にテーブル/ビューがならぶので必要なものにチェックを入れて「次へ」進みます。</li>
<li>テーブル定義の確認画面になります。列ごとにどういうカラムタイプであり、Javaのどの型で受け取るかを設定できます。<br />
ここではMySQLのDATETILE型を受け取る際の日付パターンを「dd-MM-yyyy」から「yyyy-MM-dd'T'HH:mm:ss」に変更しています。</li>
</ol><br />
日付時刻型の受け取りや日付パターンについては別途記事にしますので、ここでは詳細は割愛させていただきます。<br />
<br />
あと、これは私の感覚ですが、メタ情報が増えるとアプリが重たくなるので、出来る限り必要最低限のテーブル、ビューだけを登録しておくようにしましょう。<br />
<br />
<br />
<h2>Jobを作る</h2>データソースとロード先のテーブルをドラッグ&ドロップし、マウスで線を引きます。<br />
より直感的なインターフェイスです。<br />
<iframe width="640" height="480" src="//www.youtube.com/embed/URxZTPnzpD0?rel=0" frameborder="0" allowfullscreen></iframe><br />
<h4>ここで操作している内容</h4><ol><li>「Job Designs」を右クリックして「ジョブの作成」を選択します。</li>
<li>任意の名前をつけて「終了」をクリックします。(本来は「Purpose(目的)」や「Description(説明)」を適切に入力してください。)</li>
<li>ジョブ編集画面が開きます。</li>
<li>取得したsource1テーブルドラッグ&ドロップしてジョブエディタに乗せます。</li>
<li>コンポーネントを選択する画面が開くのでここでは「tMysqlInput」を選択します。<br />
コンポーネントの「Input」はETLのExtract(抽出)、「Output」はETLのLoad(ロード)に相当すると思ってよいと思います。</li>
<li>source1から期待する値が取得できるかを確認するために、パレットの「Logs & Errors」のなかから「tLogRow」をジョブエディタに乗せます。自動で「tLogRow_1」という名前がつきます。<br />
「tLogRow」は渡されたデータをコンソールに出力する機能があります。</li>
<li>source1から右クリックしてtLogRow_1にドラッグ&ドロップしてrow1のデータコネクタを作ります。</li>
<li>「実行」タブの「Debug Run」を開いて「トレースデバッグ」をクリックします。</li>
<li>source1から1行ずつ値が取り出されてtLogRow_1に引き渡されるのですが、row1上をどういう値が通過しているかがステージ上に表示されます。(これはトレースデバッグの場合のみです)<br />
tLogRow_1の効果でコンソール(ボタンの下)にも値が表示されています。</li>
<li>トレースデバッグは1行ずつ表示してゆくので終わるまで待っていられません。「強制終了」でとめます。</li>
<li>source1から期待する値が取得できるかを確認できたことにし、tLogRow_1を削除します。</li>
<li>今度はロード先のテーブルとしてdestination1をジョブエディタにドラッグ&ドロップします。</li>
<li>コンポーネントを選択する画面が開くのでここでは「tMysqlOutput」を選択します。<br />
「tMysqlOutputBulkExec」の方が高速なのですが、今回は他RDBMSとの画面上の互換性のある「tMysqlOutput」にします。</li>
<li>source1から右クリックしてdestination1にドラッグ&ドロップしてrow1のデータコネクタを作ります。</li>
<li>destination1をクリックして選択し、Componentタブを開きます。</li>
<li>「テーブル操作」で「テーブルのクリア」を選択します。<br />
こうしておくと、データをロードする前に「TRUNCATE TABLE」してくれます。</li>
<li>念のためこの状態でもう一度トレースデバッグします。<br />
例えば二つのテーブルの列の型に差異がある場合などはここでエラーになります。</li>
<li>問題ないとわかったら「実行」します。</li>
<li>完了するとコンソールに「終了しました」が表示され、row1の上に表示される数字が緑になります。<br />
ここでは7.97秒かかって55555行ロードしたことがわかります。</li>
</ol><br />
今回使ったデータは「<a href="http://kazina.com/dummy/" target="_blank">なんちゃって個人情報</a>」で生成したデータです。<br />
<br />
今回扱ったsource1とdestination1というテーブルは構造が全く同じものですが、テーブル構造が違う場合は抽出時のSQL文を変更するか、途中で加工する必要があります。<br />
どちらの方法も簡単なのですが、後者の方がETLツールっぽい感じですね。<br />
具体的な方法はいずれ紹介します。<br />
<br />
<br />
<h2>おわり</h2>いかがでしょう。<br />
「まったく簡単だ」と思っていただけたでしょうか。<br />
<br />
今回はtLogRowでデータを確認したりトレースデバッグしたりしているのですが、これらを省略すればトータル1分半くらいで出来てしまいます。(省略しなくても約2分。)<br />
<br />
<br />
ということでTalend Open Studio for Data Integration の紹介編はこれで終わりです。<br />
次回以降はより細かいところやトラブルシュートをちまちま書いていきたいと思います。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-40926919571652837152013-09-17T17:00:00.000+09:002013-10-29T03:04:43.207+09:00[TOSDI]Talend Open Studio for Data Integration最近この表題のETLツールを色々いじっているんですが、自分なりに理解できてきたところがあるので折角なので記事にしようと思いました。<br />
<br />
と、その前にこのアプリがなんなのかを紹介したいと思います。<br />
今回はアプリの紹介だけのエントリになります。<br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
前提として「ETLツール」をご存じない方がいるかもしれないのでまずETLツールとは何かを紹介しますね。<br />
ちょっと手抜きをしてWikipediaからかなり引用します。<br />
<br />
<h2>ETLとは</h2><div class="comment">Extract/Transform/Load(略称:ETL)とは、データウェアハウスにおける以下のような工程を指す。<br />
<dl><dt>Extract</dt>
<dd>外部の情報源からデータを抽出</dd>
<dt>Transform</dt>
<dd>抽出したデータをビジネスでの必要に応じて変換・加工</dd>
<dt>Load</dt>
<dd>最終的ターゲット(すなわちデータウェアハウス)に変換・加工済みのデータをロード</dd> </dl><i>Wikipedia: <a href="http://ja.wikipedia.org/wiki/Extract/Transform/Load" target="_blank">http://ja.wikipedia.org/wiki/Extract/Transform/Load</a> より引用</i></div><br />
「データウェアハウス」前提で書いてありますが、もともとの成り立ちはDWH向けに作られたのは事実でしょうけれど、ほとんどの製品は必ずしもDWHでしか使わないものではないと思います。<br />
<br />
<h2>ETLツール</h2>つまりETLツールとは上記ETLを実行できるツールのことを指すということになります。<br />
<div class="comment">ETLシステムはほとんどどんなプログラミング言語でも作成できるが、一から作るのは非常に大変である。このためETLツールを購入する企業が増えている。<br />
確立されたETLフレームワークを使うことで、コネクティビティとスケーラビリティが向上する。よいETLツールは様々な関係データベースを扱え、様々なファイルフォーマットを扱える。ETLツールは、企業アプリケーション統合やエンタープライズ・サービス・バスに統合され始めており、システムは全体として Extract/Transform/Load 以上の機能をカバーするようになりつつある。ETL製品は、データプロファイリング、データ品質、メタデータ機能などを含むようになっている。<br />
<i>Wikipedia: <a href="http://ja.wikipedia.org/wiki/Extract/Transform/Load" target="_blank">http://ja.wikipedia.org/wiki/Extract/Transform/Load</a> より引用</i></div>簡単に言うと、「ETLツールとはETLを簡単にできるようになるもので、ETL以外の便利機能が付いているものが増えてるよ」ということです。<br />
(引用した文の中にETLツール、ETLシステム、ETLフレームワーク、ETL製品などと言葉が濫立していて、どういう区分けで言葉遣いを変えているのかは私ははっきりはわかりませんが、ETL製品=有償ソフトウェアという意味で使っているようです。)<br />
あえて付け加えて言うと、「多くのETLツールがGUIを備えていて、データの流れが視覚的にわかりやすくなる」と言う点が大事だと思っています。<br />
<br />
そして「Talend Open Studio for Data Integration」の名前もこのページに「オープンソースのETLフレームワーク」のひとつとして紹介されています。<br />
<br />
<h2>Talend製品群</h2>「Talend Open Studio for Data Integration」がこんなに長い名前であるのにはわけがあります。<br />
<br />
まず、「Talend Open Studio for Data Integration」はフランスのTalend社の製品の一つです。<br />
(私は製品=有償ソフトウェアという意味で使いません。)<br />
Talend社は「ETLツール」だけでなく「データ品質管理」「マスタデータ管理」など複数の製品を作っており、それらを組み合わせることで企業のデータ管理の統合ソリューションを成立させようとしています。<br />
他にどんなソフトウェアがあるかはTalend社のサイトを見ていただければと思います。<br />
(日本法人もあり、サイトの大部分は日本語化されています。)<br />
<a href="http://jp.talend.com/" target="_blank">http://jp.talend.com/</a><br />
<br />
そしてTalend社は大部分のソフトウェアについて、有償版と無償版を提供していて、これら製品群の中で無償版のものに「Talend Open Studio for ~」の名前をつけています。(有償版のものは「Talend Enterprise ~」または「Platform for ~」)<br />
<br />
有償版と無償版の違いはほとんどの場合「追加機能の有無」と「サポートの有無」だと思われます。<br />
有償版のお値段はサイト上で公開されていませんので、どこか取り扱いのある国内代理店さんにお問い合わせいただければと思います。<br />
(私も見積をもらったことがありますが、単品ではビックリするほどの値段ではありませんでした。もちろん個人で払える値段ではありませんが。)<br />
<br />
(遠回りしましたが)Talend社の製品群の中で無償のETLツールが「Talend Open Studio for Data Integration」です。<br />
製品公式ページは以下のURLです。有償版と無償版の違いもここに書かれています。<br />
<a href="http://jp.talend.com/products/data-integration" target="_blank">http://jp.talend.com/products/data-integration</a><br />
<br />
<h2>Talend Open Studio for Data Integration</h2>さて、いよいよ本題です。といっても言いたいことは残りわずかです。<br />
以下略してTOSDIと書きます。<br />
<br />
TOSDIはEclipseベースで作られていて、つまりJavaで動きます。<br />
ほとんどの主要OS(Linux、MacOSX、Windows)で動き、ほとんどの主要DBMSと接続できます。<br />
(ただし、有償版でないと接続できないものも一部ある模様)<br />
また、DBMSだけでなくCSVやExcelなどのファイルもデータソース、ロード先として利用できます。<br />
日本語版があり、大部分が日本語化されています。<br />
<br />
<h2>必要スキル</h2>TOSDIを扱うにあたって最低限必要なスキルは利用するDBMSに関する基礎知識です。<br />
当然SQL文は理解/記述できたほうが有利です。<br />
<br />
基本的な作業はGUIで出来るのでプログラミングの知識は不要ですが、パーツにJavaのコードを埋め込むことでより高度なデータ操作を行うことができます。<br />
GUIで組み立てた一連の(ジョブと呼ぶ)流れは、当然内部的にJavaのコードが生成されているのですが、これも作成中いつでも参照することができます。<br />
エラーはJavaのエラーや例外で出力されます。<br />
<br />
つまり何がいいたいかというと、このツールを使いこなすには「SQLだけでなくJavaの知識があったほうがいい」ということです。<br />
<br />
<br />
今回はここまで。<br />
次回は紹介の続きで、「基本的な作業はGUIで出来る」っていうのを動画を交えて紹介しようと思います。<br />
<br />
<br />
<a href="http://dupont-kedama.blogspot.com/p/blog-page.html">Talend Open Studio for Data Integration関連エントリまとめ</a><br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-76190879299304243572013-08-31T17:00:00.000+09:002013-08-31T17:00:02.019+09:00[Windows]監視スクリプトを書いてみた のおまけ(言い訳)<h3>VBScriptのコードが冗長な言い訳</h3><br />
前回まで監視のスクリプトを書いてきたわけですが、このシリーズのVBScriptのコードはsendMail.vbs以外でかなりのダブりがあり、無駄があります。<br />
このダブりをなくす方法がないわけではないのですが、あえて無駄な状態で公開しました。<br />
<br />
<a name='more'></a><br />
<br />
その訳を説明します。<br />
<b>「VBScriptのクラスは継承の機能を持たない」</b><br />
全く同じ関数/サブルーチン(以下関数)や同名同目的の関数があるので、抽象クラスを作って継承して作るのが妥当に思われるかもしれません。<br />
VBScriptでもクラスは作れますが、継承が出来ないのです。<br />
検索すると「擬似的にクラスの継承のようなことをする」やり方もありますが、この程度の規模のコードでそれを採用すること自体かなり冗長です。<br />
<br />
<b>「単体で使いやすく」</b><br />
取り回しの問題です。sendMail.vbsだけは外部ファイル化してますが、それ以外は出来るだけファイル単体で使いやすくしたかったのです。<br />
また、分離することで、内容を変更した場合の影響範囲がわかりやすくなります。<br />
<br />
<b>「sendMail.vbsだけ外部ファイル化」した訳</b><br />
共通の関数の中で、環境依存の変数が必要なのはログファイルのディレクトリだけなのに比べて、sendMailだけは環境依存変数が特に多く、最大8項目あります。<br />
これを個々に持たせるのは流石にアレですよね。<br />
まぁ、ログディレクトリを個々に持たせてるのもアレなんですが。<br />
<br />
<br />
<h3>今後の発展</h3>直近で予定しているものはないですが、発展させるとしたら<br />
・複数ファイルになるけどやっぱりクラス化して冗長をなくしつつ計量化。<br />
・もっとスマートにWMIとか使う。(<a href="http://www.wmifun.net/sample/win32_service_g.html" target="_blank">Win32_Service</a>)<br />
・いやそろそろPowerShellで出来るところはそっちに移行。<br />
とかですかね。<br />
<br />
このコードを書いていたころはまだクライアントもWindowsXPだったので、デフォルトで入っていないPowerShellは使わない方針でしたが、XPのサポートも来年で切れ、ほとんどすべてのWindowsにおいて標準でPowerShellが入っている環境になります。<br />
<br />
<br />
<br />
無限ループしても警告してくれないし、クラスの継承はできないし、例外処理もまともにできないし、色々かゆいところに手が届かないけど、<br />
デフォルトの環境(メモ帳)でチョチョっと編集でき、デフォルトの環境で実行でき、事前コンパイルが要らず、一応クラスも書ける。<br />
超絶に中途半端だけどお手軽なVBScriptはまだまだ活用するシーンがあるんではないかと思っておる次第です。<br />
<br />
今後はVBScriptなエントリが増えるかもしれないです。<br />
Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-36635723874640111612013-08-30T18:00:00.000+09:002013-08-30T18:00:06.595+09:00[Windows]監視スクリプトを書いてみた(5/5) MySQLレプリケーション監視ApacheやらMySQLのサービスが落ちてないかなどを監視するのを自分でチェックして異常があったら発報する仕組みが必要だと思ってました。<br />
サードパーティに頼らず、WindowsOSの機能だけで作ってみたかったので、ほぼVBScriptだけでくみ上げてみました。<br />
<br />
そんな<b>マゾヒズム感全開なエントリ</b>がこちらです。<br />
<br />
今回は第5回です。<br />
<ol><li><a href="http://dupont-kedama.blogspot.com/2013/08/windows15.html">処理フロー</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows25.html">メール送信</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows35.html">サービス監視</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows45.html">ポート監視</a></li>
<li><b>MySQLレプリケーション監視</b>(今回)</li>
</ol><br />
<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>内容</h2>MySQLのレプリケーションのスレーブのステータスを確認します。<br />
MySQLのインスタンスとして問題なくてもレプリケーションの動作だけおかしいという場合はありえる話で、参照はできるけど実は2時間前にレプリケーションが止まっていて2時間前のデータを見ているなんてことも起こりうるということです。<br />
なので特にスレーブステータスのエラーや遅延秒数をチェックします。<br />
<br />
<br />
<h2>使い方</h2>前回のサービス監視とほぼ同じですがこのスクリプトは可変な変数が多いため、引数をとりません。<br />
下のVBScriptと第2回で紹介したsendMail.vbsを同じディレクトリに置き、さらにバッチファイルを置いて以下のように記述します。<br />
<pre class="border">Call watchReplication.vbs</pre>ポート番号他の各設定値はスクリプト内に記載します。<br />
複数のスレーブインスタンスを監視したい場合は、ファイル名を変えて以下のようにすればよいでしょう。<br />
<pre class="border">Call watchReplication_3307.vbs
Call watchReplication_3308.vbs</pre><br />
<br />
<h2>ポイント</h2>今回使うコマンドは(3307ポートの場合)<br />
<pre class="border">mysql -P3307 -umysql_user -pmysql_pass -e"SHOW SLAVE STATUS\G"</pre>です。<br />
これを分解すると、<br />
<pre class="border">-P ポート指定
-u ユーザー名指定
-p パスワード指定
-e SQL文指定
</pre>オプションの後ろは余白が要りません。特に-pの後ろは余白があるとその余白もパスワードの一部と誤認してしまうので注意が必要です。<br />
また、5.6.10以降は-pオプションを使用すると「Warning: Using a password on the command line interface can be insecure.」が出ます。<br />
(Warningが出ても今回の内容の目的は果たせますが、セキュアにしたい方、Warningを出したくない方はそれなりの対処をしてください。方法の説明はここでは省略します。)<br />
SQL文のデリミタは;ではなく\Gをつけてフィールドごとに行で出力させるようにします。<br />
<br />
そしてこの出力の中で以下の項目をチェックします。<br />
<dl><dt>Slave_IO_State</dt>
<dd>「Waiting for master to send event」かどうか</dd>
<dt>Slave_IO_Running</dt>
<dd>「Yes」かどうか</dd>
<dt>Slave_SQL_Running</dt>
<dd>「Yes」かどうか</dd>
<dt>Last_Error</dt>
<dd>(空)かどうか</dd>
<dt>Last_IO_Error</dt>
<dd>(空)かどうか</dd>
<dt>Seconds_Behind_Master</dt>
<dd>指定した数値以下かどうか</dd> </dl>※Seconds_Behind_Masterの上限値として変数に値を入れますが、このスクリプトが実行したときのステータス値しかチェックできません。<br />
日常の上限値ではありませんのでご注意ください。<br />
<br />
<br />
<script src="https://gist.github.com/dupont-kedama/6328283.js"></script><br />
<br />
<br />
<h2>冗長なコード</h2>さて、このシリーズを毎回まじめに読まれた奇特な方は、VBScriptのコードが少し、いやかなり冗長で無駄が多いように思われたかもしれません。<br />
私なりに整理した結果こうなっているのですが、その言い訳はまた別の機会に。<br />
<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-2788903754664700732013-08-29T23:52:00.000+09:002013-08-29T23:52:00.646+09:00[Windows]監視スクリプトを書いてみた(4/5) ポート監視ApacheやらMySQLのサービスが落ちてないかなどを監視するのを自分でチェックして異常があったら発報する仕組みが必要だと思ってました。<br />
サードパーティに頼らず、WindowsOSの機能だけで作ってみたかったので、ほぼVBScriptだけでくみ上げてみました。<br />
<br />
そんな<b>マゾヒズム感全開なエントリ</b>がこちらです。<br />
<br />
今回は第4回です。<br />
<ol><li><a href="http://dupont-kedama.blogspot.com/2013/08/windows15.html">処理フロー</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows25.html">メール送信</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows35.html">サービス監視</a></li>
<li><b>ポート監視</b>(今回)</li>
<li>MySQLレプリケーション監視</li>
</ol><br />
<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>内容</h2>引数で指定したポートが待ち受け状態にあるかを確認します。<br />
サービスにくわえてポートまで監視する必要性は薄いように思われるかもしれませんが、「サービスは開始されていてもポートが待ちうけ状態にない」ことはありえることです。<br />
特にIISで稼動するWebサイトは複数のポートで配置することができ、サービスの稼動とサイトの稼動は別の制御になっています。<br />
最近ApacheからIISに移行した私にとっては重要かもしれない監視になるのです。<br />
<br />
<h2>使い方</h2>前回のサービス監視とほぼ同じです。<br />
下のVBScriptと第2回で紹介したsendMail.vbsを同じディレクトリに置き、さらにバッチファイルを置いて以下のように記述します。<br />
<pre class="border">Call watchPort.vbs 80</pre>複数のポートを監視したい場合は以下のように記載します。<br />
<pre class="border">Call watchPort.vbs 80
Call watchPort.vbs 3306
Call watchPort.vbs 21</pre><br />
<h2>ポイント</h2>今回使うコマンドは<br />
<pre class="border">NETSTAT -an|FIND "TCP"|FIND "0.0.0.0"</pre>です。<br />
これを分解すると、<br />
<pre class="border">NETSTAT -an</pre>すべてのアクティブなTCP接続とコンピュータがリッスンしているTCPとUDPポートを表示します。ここから<br />
<pre class="border">FIND "TCP"</pre>でプロトコルがTCPのものだけを拾い、さらに<br />
<pre class="border">FIND "0.0.0.0"</pre>でコンピュータがリッスンしているものに絞り込みます。<br />
<br />
この出力の中から完全一致の行を見つけるために正規表現で検索しています。<br />
例えば80番ポートを検索する場合の正規表現パターンはこうなります。<br />
<pre class="border">"TCP\s*0.0.0.0:80\s.*LISTENING"</pre>VBScriptで使える正規表現では特定のデリミタがなく、"で囲みます。<br />
<br />
<script src="https://gist.github.com/dupont-kedama/6328279.js"></script><br />
<br />
サービス監視よりも少し簡単ですね。<br />
<br />
さて次回はMySQLのレプリケーション監視です。<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-36801985933766467592013-08-28T18:00:00.000+09:002013-08-30T01:52:47.932+09:00[Windows]監視スクリプトを書いてみた(3/5) サービス監視ApacheやらMySQLのサービスが落ちてないかなどを監視するのを自分でチェックして異常があったら発報する仕組みが必要だと思ってました。<br />
サードパーティに頼らず、WindowsOSの機能だけで作ってみたかったので、ほぼVBScriptだけでくみ上げてみました。<br />
<br />
そんな<b>マゾヒズム感全開なエントリ</b>がこちらです。<br />
<br />
今回は第3回です。<br />
<ol><li><a href="http://dupont-kedama.blogspot.com/2013/08/windows15.html">処理フロー</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows25.html">メール送信</a></li>
<li><b>サービス監視(今回)</b></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows45.html">ポート監視</a></li>
<li>MySQLレプリケーション監視</li>
</ol><br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.2em;
}
div.border,
pre.border {
margin: 0.2px 10px;
padding-left: 1em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>内容</h2>引数で指定したサービスが開始の状態になっているかをチェックします。<br />
WindowsだとApacheのサービスがいつのまにか落ちてるなんてことが・・・私の場合はありました。<br />
通常営業時間中であればすぐに周りが騒ぎ始めるのですぐ気づくんですが、夜間とかはまぁ気づかないのでご迷惑をおかけしてしまうわけで、このシリーズを書くことになったきっかけです。<br />
<br />
<h2>使い方</h2>下のVBScriptと第2回で紹介したsendMail.vbsを同じディレクトリに置き、さらにバッチファイルを置いて以下のように記述します。<br />
<pre class="border">Call watchService.vbs "Apache2.2"</pre>通常「.vbs」は自動で探しに行く拡張子なので、「watchService.vbs」は「watchService」に省略可能ですが、仮に同じディレクトリにwatchService.batとかあるとそちらを先に見に行ってしまうので注意してください。(末尾に余談記載あり)<br />
複数のサービスを監視したい場合は以下のように記載します。<br />
<pre class="border">Call watchService.vbs "Apache2.2"
Call watchService.vbs "mysqld"
Call watchService.vbs "mongod"</pre><br />
<br />
<h2>ポイント</h2>VBScriptでちゃんとやる方法もあるとは思うのですが、スクリプトの中でコマンドプロンプトを呼び出してNETコマンドを実行し、その結果の標準出力を解析して状態を確認するという、かなりの手抜きをしています。<br />
(なお、この手法はこのシリーズ共通です。)<br />
<br />
使っているコマンドは<br />
<pre class="border">NET START|FIND /i サービス表示名</pre>です。<br />
これを分解すると、<br />
<pre class="border">NET START</pre>で開始されているサービスの一覧を取得します。ここで一覧されるのはサービス名ではなく、サービス表示名であることにご注意ください。コマンドプロンプトで実行するとこんな感じで出力されます。<br />
<img border="0" src="http://4.bp.blogspot.com/-g3QThKjkYTk/UhjUBljGOdI/AAAAAAAAAkc/q_TjN4nO5cM/s1600/netstart1.png" /><br />
<br />
で、これをパイプで<br />
<pre class="border">FIND /i サービス表示名</pre>に渡して絞り込みます。上記のものを「epson」で絞り込むとこうなります。「/i」は「大文字小文字を区別しない」オプション指定です。<br />
<img border="0" src="http://1.bp.blogspot.com/-EuASE-BUkxk/UhjUDyNbUXI/AAAAAAAAAkk/HXGNJ0ky2To/s1600/netstart2.png" /><br />
みていただければわかるとおり、FINDは部分一致での検索なので、例えば mysqld と mysqld_slave というサービス表示名があったときに mysqldで検索しても両方ヒットして2行出力されてしまいます。<br />
そこでその後でこの出力の中から完全一致の行を見つけるために正規表現で検索しています。<br />
<br />
それから、フラグファイルやログファイルにこのサービス名を使っているのですが、サービス表示名にはスペースが使われていることがあります。<br />
これをそのままファイル名に使うと後が面倒なので、フラグファイル名とログファイル名ではスペースを_に置き換えています。<br />
例) 「World Wide Web Publishing Service」 → 「World_Wide_Web_Publishing_Service.log」<br />
<script src="https://gist.github.com/dupont-kedama/6328271.js"></script><br />
<br />
ログファイルは月ごとにローテーションさせています。好きに変えてください。このシリーズ共通です。<br />
メール送信はこのシリーズ第二回で紹介したsendMail.vbsを使います。このシリーズ共通です。<br />
<br />
<br />
<h2>余談</h2>自動で探しに行く拡張子と順番は<br />
<pre class="border">ECHO %PATHEXT%</pre>のコマンドで確認できます。<br />
<img src="http://4.bp.blogspot.com/-ih2NTDWnbTk/UhjaTS0xzmI/AAAAAAAAAk0/jBWZaTUh0GM/s1600/pathext.png" /><br />
これはシステム環境変数で、管理者権限があれば変更できます。<br />
<img border="0" src="http://1.bp.blogspot.com/-gjhniUr7IuE/UhjcYWLR7NI/AAAAAAAAAlA/iE1MCcLuolg/s1600/pathext2.png" /><br />
<br />
さて、次回はポート監視です。<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com3tag:blogger.com,1999:blog-3115486693488874682.post-73982986588759622472013-08-27T18:00:00.000+09:002013-08-30T01:53:04.008+09:00[Windows]監視スクリプトを書いてみた(2/5) メール送信ApacheやらMySQLのサービスが落ちてないかなどを監視するのを自分でチェックして異常があったら発報する仕組みが必要だと思ってました。<br />
サードパーティに頼らず、WindowsOSの機能だけで作ってみたかったので、ほぼVBScriptだけでくみ上げてみました。<br />
<br />
そんな<b>マゾヒズム感全開なエントリ</b>がこちらです。<br />
<br />
今回は第2回です。<br />
<ol><li><a href="http://dupont-kedama.blogspot.com/2013/08/windows15.html">処理フロー</a></li>
<li><b>メール送信(今回)</b></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows35.html">サービス監視</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows45.html">ポート監視</a></li>
<li>MySQLレプリケーション監視</li>
</ol><br />
<br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.5em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>必要性</h2>「発報」はMSのIMEの漢字変換で出てこないんですが、多分業界では一般的な言葉だと思います。<br />
無人で監視しているシステムで異常が起こって、その監視しているPCや監視対象のサーバー上でエラーダイアログが出ても、気づくことはできませんので、異常を検知したらメールでお知らせしてくれるようにします。<br />
24時間の監視をするなら、携帯メールも送信先に入れておく必要もあるかもしれませんね。<br />
<br />
<h2>コード</h2>「VBScript+メール送信」で検索すればコードはごろごろ転がってるんで、それを参考に書き直してみました。<br />
このシリーズではメール送信単体で使うことはなく、「異常を検知したらそれを知らせる」必要があり、それに適した形に書いています。<br />
<br />
ポイントはこのスクリプトを単体のファイルとして保存し、外部ファイルから呼び出せるようにすること。<br />
呼び出すときに件名と本文を指定できるよう、引数を受け入れること。<br />
自らがSMTPサーバー機能を持っていなくてもよいように、外部のSMTPサーバーに接続するパターンにしています。<br />
<br />
<script src="https://gist.github.com/dupont-kedama/6328247.js"></script><br />
例えば社内ネットワークの中にあるSMTPサーバーなど、自由に接続できる場合はよいのですが、接続するのにユーザー名/パスワードが必要になるなら25,26,82,83,84行目のコメントアウトを外して適宜変更してください。<br />
<br />
本文エンコードは一応「ISO-2022-JP」にしていて、ほとんどのメールクライアントはこの文字コードに対応していると思っていますが、文字化けして読めないようなら変えてください。<br />
(iPhoneのメールとWindows版Outlook2003,2010では読めることを確認しています。)<br />
<br />
<br />
次回はVBScriptでサービス監視をします。<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0tag:blogger.com,1999:blog-3115486693488874682.post-72269544508605650852013-08-26T18:00:00.000+09:002013-08-30T01:53:20.763+09:00[Windows]監視スクリプトを書いてみた(1/5) 処理フローはApacheやらMySQLのサービスが落ちてないかなどを監視するのを自分でチェックして異常があったら発報する仕組みが必要だと思ってました。<br />
サードパーティに頼らず、WindowsOSの機能だけで作ってみたかったので、ほぼVBScriptだけでくみ上げてみました。<br />
<br />
そんな<b>マゾヒズム感全開なエントリ</b>がこちらです。<br />
<br />
今回から5回にわたりコード含めて紹介したいと思います。<br />
<ol><li><b>処理フロー(今回)</b></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows25.html">メール送信</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows35.html">サービス監視</a></li>
<li><a href="http://dupont-kedama.blogspot.com/2013/08/windows45.html">ポート監視</a></li>
<li>MySQLレプリケーション監視</li>
</ol><br />
<style>
div.comment
{
overflow: auto;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
-webkit-box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
box-shadow: 0.2em 0.2em 0.5em rgb(100, 100, 100);
border: 1px solid #CCCCCC;
background-color: #EEFFEE;
padding: 5px;
margin: 10px;
}
div.comment.caution {
background-color: #FFDDFF;
}
div.comment.explain {
background-color: #EEEEFF;
}
h2
{
border-bottom: 1px solid #AAAACC;
padding-left: 10px;
font-size: 1.2em;
color: #333;
}
dl dd{
margin-left: 20px;
margin-bottom: 8px;
}
.w {
color: #FFFFFF;
}
.border,
.border td,
.border th {
border: 1px solid #0055AA;
border-collapse: collapse;
padding: 0.5em;
}
th {
background-color: #EEEEFF;
}
img.img {
border: solid #666 2px;
box-shadow: 3px 3px 5px #aaa;
max-width: 670px;
}
</style><br />
<a name='more'></a><br />
<b class="w">.</b><br />
<br />
<h2>処理ルーチン</h2>以下の処理を行うバッチファイルを作り、これをタスクスケジューラで5~10分ごとに実行するよう仕込みます。<br />
<br />
バッチファイルの中身は以下の通りです。<br />
<div class="comment">システム障害がないかをチェックします。<br />
<br />
システム障害がなければ「正常」としてログファイルにログを記録して終了です。<br />
<br />
システム障害が検知されたら「障害発生」としてメールで発報します。<br />
ログファイルにログを記録して終了します。</div><br />
<br />
<h2>障害継続の場合の処理</h2>ただ、これだけだと次回までに復旧できないと「システム障害を検視した」としてまたメールを(10分おきに)送信してしまいます。<br />
またメールが来なくなったら障害が復旧したのかなと思うわけです。<br />
これではちょっと頭悪そうなので工夫が必要だと思いました。<br />
<br />
<div class="comment">システム障害がないかをチェックします。<br />
<br />
異常がなければ「正常」としてログファイルにログを記録して終了です。<br />
<br />
異常があれば「障害発生」としてメールで発報します。<br />
<b>さらに障害が発生していることをローカルに記録するフラグファイルを生成します。</b><br />
ログファイルにログを記録して終了します。</div><br />
<br />
すでにフラグファイルがある場合は以下の動作になります。<br />
<div class="comment">システム障害がないかをチェックします。<br />
<br />
異常がなければ「障害復旧」として、フラグファイルを削除し、復旧通知のメールを送信します。<br />
ログファイルにログを記録して終了です。<br />
<br />
異常があれば「障害継続」として、発報はせず、ログファイルにログを記録して終了です。</div><br />
<br />
<br />
<h2>フローチャート</h2>この処理をフローチャート風にするとこんな感じでしょうか。<br />
(フラグファイル有無の確認と障害検知の順番をちょっと変えています。)<br />
<iframe src="https://cacoo.com/diagrams/fFYsufPAASO3OfwK/view" width="402" height="330" frameborder="0" scrolling="no"></iframe><br />
(Cacooのフローチャートのセットにはサブルーチンのステンシルがないのね。)<br />
<br />
なお、このシリーズではすべてローカルのサービスやポートなどを監視する前提です。<br />
リモートの監視については工夫すればできるものもありますが、今回は触れません。<br />
<br />
<br />
次回はメールをVBScriptで送信してみます。<br />
<br />
<b class="w">.</b>Duponthttp://www.blogger.com/profile/18034351731655448436noreply@blogger.com0