2017年1月28日土曜日

SQLServer 2008 から Merge が使える

久しぶりに本題のSQLServer です。

今まで知りませんでした。
MERGE文が使えるんですね。

SQL と言えば、言わずもがな「Select」「Insert」「Update」「Delete」の4文が基本です。
例えば、Table_A と、ほぼ同じ構造を持った Table_B があって、
必ずTable_Aが最新になっているとします。

最新になっているというのは、

1、レコードが増えている。
2、レコードが減っている。
3、レコードが更新されている。

とうことが考えられます。

この状態をTable_Bに反映させる。
例えば、夜間バッチでTable_Bを最新状態にする必要がある場合が想定されます。

今までなら、
Table_Bに不足しているレコードを特定して、Insert文を発行。
Table_Aには無いレコードを特定して、Delete文を発行。
Table_AにもTable_Bにもあるが、更新されているレコードに対して、Update文を発行。
と3回の比較処理を走らせる必要があるので、
大量のレコードの場合に、莫大なコストが必要になることがありました。

これを1回の比較で処理してしまうのが、Merge です。
まあ、言葉の意味のままのステートメントです。

私の場合、ORACLEにあるテーブルをそのままSQLServerに毎日夜間バッチでコピーしたいのですが、総レコード数は40万件以上あるのに、更新または追加されるのは、わずか1000件程度。
その1000件を最新に保つために、 Truncate で全消し、Insert で全書きをしていましたが、あまりにも非効率なのと、ディスクにも負担をかけると思います。

そこで考えたのが、リンクサーバーでORACLEに接続して、OpenQuery を発行します。
その際、更新年月日を参照して、前回処理日以降だけに絞る Where句を付けておきます。
OpenQuery なので、条件が入っても、ORACLE側で高速に処理されて返ってきます。
これで1000件程度のレコードが返ってくる。

これを一旦 Select Into ##tempTable で仮テーブルに保管して、SQLServer 側の本来保管したいテーブルと比較して、 MERGE 処理を行うことにしました。

毎日数分かかっていた処理が、数秒で完了するようになりました。

MERGE の構文自体は、他の方がたくさん例を挙げていただいているので、私は省略です。

でも、1行で書けるといっても、結構手間の必要な構文になります。

比較は1回ですが、マッチした場合の動作(通常は UpDate になるかな。)と、アンマッチの場合の動作を(私の場合は、Insert ですが、 場合によっては、 Delete になる。)それぞれ書かないとダメです。
まあ、当たり前と言えば当たり前ですけどね。

特に、 UpDate の場合は、カラムを全部書かないと(しかも、元と先の両方を書かないと)ダメなので、カラム数の多いテーブルだと、長ーい構文になっちゃいます。







UQモバイルで SIMロック解除が必要

auからUQモバイルに乗り換えを考える場合、SIMロック解除が必要なのかどうかがよく理解できていませんでしたが、身をもって確認できました。

確認したのはXperia 限定のことです。

2016年11月ごろに中古市場で au仕様のXperia Z1 (SOL23) を購入しました。新品未使用状態です。
すぐに UQモバイルに申し込み、数日でSIMが到着。
本体にSIMをセットしてAPNを設定したらすぐに使えました。
「なーんや、SIMロック解除って必要ないやん。」

これは、au仕様の端末でUQモバイルのSIMだから解除が必要ないんだと解釈しました。

これに気をよくして、今度は2016年末に同じくau仕様の Xperia Z4(SOV31) を、これまた中古市場で、新品未使用品を購入しました。
お値段は33000円ぐらいだったと思います。

これも早速 UQモバイルの SIM を挿しましたが、今度は通信できません。
なんで?同じ au仕様で UQモバイルやから問題ないはず。
とおもったのですが、大きな勘違いでした。

au仕様の端末で UQモバイルのSIMを使う場合で、ロック解除が不要のまま使えるのは、Z1が最後の機種のようです。
Z1以降に発売された端末は SIMロック解除が必要だそうです。

20170627訂正
Z3もロック解除必要なしが確認できました。
因みに、Z2 Tablet もロック解除必要なしが確認できました。

なんか、総務省かなんかが SIMロック解除を命令したようですが、逆に邪魔臭くなってるような気がする。

おかげで、(私は)年末に買ったのに、最初の所有者が購入した後、6ヶ月間は解除できないので、私の場合、2月初旬まで解除できません。
今のところ、UQの契約はしたままなので、月額1000円を捨てているような状態。(通信していないので、月3Gの容量をどんどん持ち越していて、2月に使えるようになったら、9Gぐらいからスタートすることになります。

20170627訂正
UQMobileの持ち越しは1ケ月分だけでした。
なので、MAXでも6Gにしかなりません。

Z4自体は前に使っていたスマホ(Xperia UL SOL22)をUQモバイルで契約して、それにBluetoothでWIFI接続して使っています。

2月になればすぐにロック解除するつもりですが、これまた、auのサイトを読んでいると、契約者でないとネット解除できないような感じ。
ということは、auショップに持ち込んで3000円払って解除してもらわないとだめなのか~。