第3回 関西DB勉強会 明日開催です!

明日開催なのですが、若干空きが出来たので宣伝~。

第3回 関西DB勉強会 - 関西DB勉強会 | Doorkeeper

このメンバーで、各DBのプロフェッショナル達がホワイトボード中心で徹底的にアーキテクチャの違いを議論します。

Oracle:小幡一郎 (株)インサイトテクノロジー代表
MySQL:山﨑 由章 (日本オラクル株式会社 MySQL GBU)
PostgreSQL:曽根 壮大(日本PostgreSQLユーザ会)
Firebird/MySQL:木村明治 Firebird日本ユーザー会
SQL Server:小澤真之 フリーランス (Microsoft MVP for Data Pratform)
DB2 :寺元良一 三木会(インサイトテクノロジー主催)

どんな風になるのか楽しみ!
ご都合の良い方は是非~。

T-SQL FORMATMESSAGE の機能強化

SQL Server 2016 で強化された T-SQL で、開発時にクエリ書く人が使いそうなのをピックアップして取り上げてみようと思います。

SQL Server 2016 RC3 から FORMATMESSAGE が引数に、メッセージ番号だけではなく任意の文字列を受け取れるようになりました。
FORMATMESSAGE (Transact-SQL)

FORMATMESSAGE が元々どういうものかと言うと

SELECT text FROM sys.messages WHERE message_id = 20009 AND language_id = 1033;
DECLARE @var1 VARCHAR(200); 
SELECT @var1 = FORMATMESSAGE(20009, 'First Variable', 'Second Variable'); 
SELECT @var1; -- The article 'First Variable' could not be added to the publication 'Second Variable'.

こんな感じのやつです。
sys.messages の message_id を渡して、文字列を作成するってやつです。
これが message_id ではなく、任意の文字列を受け取れるようになりました。
メッセージの文字列は、RAISERROR (Transact-SQL) の msg_str と同じ制限があります。
例えば上と同じ結果を返そうとすると以下のクエリになります。

select FORMATMESSAGE('The article ''%s'' could not be added to the publication ''%s''.', 'First Variable', 'Second Variable');

String.Format メソッド (String, Object[]) (System) のような感じで使えます。
sys.messages 関係無く使えるので、別の関数名で新しく作っても良かったのでは?と思いましたが、
この機能アンドキュメントなだけで、2016 より前のバージョンでも使えました。
検証のため全部同じクエリで試しています。

SQL Server 2016

ドキュメント通り使えます。

SQL Database v12

SQL DB はまあ使えて当然な感じ。

SQL Server 2014

2014 でも使えますね~。

SQL Server 2012

なんと 2012 でも使えます。

SQL Server 2008

さすがに 2008 は無理でした。


というわけで、2012 以降から使えそうですね。
もともと使えてたから、関数名も変えずにそのままでってところなんでしょうか。
引数は、文字列リテラルに限らずテーブルの列やサブクエリも書けるので自前のメッセージテーブルから使うことも出来ます。

例:sys.messages を自前のメッセージテーブルと思ってください。

select FORMATMESSAGE( 
  (SELECT text FROM sys.messages WHERE message_id = 20009 AND language_id = 1033)
  , 'First Variable'
  , 'Second Variable'
)

select FORMATMESSAGE(text, 'First Variable'  , 'Second Variable') FROM sys.messages

5/18(水) SQLWorld★大阪#37 開催します

2週間前の告知! SqlWorld :: SQLWorld★大阪#37 開催します。19回目の平日夜開催で、前回同様 ハンズオン 形式行う予定です。

【日時】
2016年5月18日(水曜日) 19:00~21:00
 

【イベント概要】
SQLWorld 19回目の平日夜開催~。今回も、みんなで SQL を書いてみようというハンズオン企画です!ブラウザがあれば参加出来るようにしていますので、iPad 等のタブレットでも大丈夫です。
 

【会場】
フェンリル株式会社さま大阪本社 http://www.fenrir-inc.com/
〒530-0011 大阪府大阪市北区大深町 3番1号 グランフロント大阪タワーB(オフィス) 14F
http://info.fenrir-inc.com/jp/profile/overview.html
 

【参加費】
無料
 

【持ち物】
パソコン/タブレット (DB のインストールは不要です。)
 

【参加可能人数】
13 人
 

お題に沿って、SQL を書いてみようという勉強会です。是非ご参加を~。

開催回数は増えていっていますが、続き物というわけでは無いので初めて参加される方でもお気軽にどぞー。

SQL Database Basic/Standard でも Active Geo Replication がサポートされました

azure.microsoft.com

Active Geo Replication が Basic / Standard でも使えるようになりました。

これに伴い、Standard / Premium で使えた、Standard Geo Replication は 2017/04 で廃止になります。

Standard Geo Replication が Active Geo Replication に勝ってるとこは、セカンダリの価格位かな?
2台目が * 0.75 だったのが * 1 倍の価格になってしまうのがネックですかね。

Azure WebApps サイト単位で IP 制限をする

Build とか SQL Server 2016 RC1 とかの話題が出てますが、気にせずメモ書き。

Microsoft Azure Web Site Cheat Sheet
Cheap and easy IP blocking in Azure Web Apps – Shawn Cicoria

Web.config に書けばいいんですが、諸々の事情でサイト毎に設定したい場合のメモ。

d:\home\site に applicationHost.xdt を配置する。

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <location path="サイト名" xdt:Locator="Match(path)" xdt:Transform="InsertIfMissing">
    <system.webServer xdt:Transform="InsertIfMissing">
      <security xdt:Transform="InsertIfMissing">
        <ipSecurity allowUnlisted="false" denyAction="NotFound" xdt:Transform="Replace">
          <add allowed="true" ipAddress="許可するIP" xdt:Transform="InsertIfMissing"/>
        </ipSecurity>
      </security>
    </system.webServer>
  </location>
</configuration>

location 指定しないと、kudo や site extensions の方*1に対して設定されてしまいました。
これで kudo に繋がらなくなったりします。 そうなった場合は、FTP から applicationHost.xdt を削除すると設定も解除されました。

*1:~.scm.azurewebsites.net

T-SQL 非決定的関数やサブクエリを case / choose / coalesce の条件部で使うときは注意が必要!

T-SQL でズンドコキヨシを書こうとして気付いたのですが、

select case cast(RAND() * 100 as int) % 2 + 1 
  when 1 then N'ズン' 
  when 2 then N'ドコ' 
  else '意図していない!' end

これが '意図していない!' を返す時があったり、

select choose(cast(RAND() * 100 as int) % 2 + 1, N'ズン', N'ドコ')

これが null を返す時があります。

バグってるのかと思って調べてみると以下のサイトが見つかりました。
SQL Server CASE Law
COALESCE((subquery), 1) may return NULL | Microsoft Connect

ここでは coalesce ですが、case / choose も同じようです。

非決定的な関数の場合、条件判定の際に、複数回実行するそうです。

case の例だと、1つ目の条件(when 1)の時の実行結果が 2 で、2つ目の条件(when 2)の時の実行結果が 1 になると、else の '意図していない!' になってしまうという。
choose も中で同じような事やってるんですかねー。

上の記事でも書いてる通り、条件決める値は1回だけの実行が直感的で良いと思うけど。。

これ調べててズンドコキヨシ書けてない。。

メモ:Azure WebApps で 1つのリポジトリに複数の Webアプリがある時のデプロイ

Deploying TWO websites to Windows Azure from one Git Repository - Scott Hanselman

WebApps の Application settings の app settings に Project = Webアプリ.*proj を指定するだけでOK。

WebJobs だけを載せる場合も同様に、コンソールアプリ.*proj でOK。

ちなみに、WebApps と WebJobs を一緒に載せる場合は、
WebJobs を含むソリューションを Azure Web Apps へソース管理からデプロイする方法 - しばやん雑記
で紹介されている カスタムデプロイスクリプト でもいいですし、
Webアプリの .*proj ファイルの AfterBuild で コンソールアプリをビルドして、WebApps の App_Data 以下に配置する方法でもいけました。