2009年7月2日木曜日

SQL-Server 2008 Expressと、Management Studio 2008に感動しました!






マイクロソフトが公開してくれた、無料のRDBMSである「SQL-Server 2008 Express」と、その管理ツールである「SQL-Server Management Studio 2008」ですが、もしかすると今年一番感動したソフトウェアになるかも知れません。

■SQL-Serverって?■

SQL-Serverは、今や、大企業が自社の基幹システムにも採用しているほどのメジャーなデータベースです。もちろん、高価なソフトウェアなんですが、どうしたことか、SQL-Server 2005からは、Expressというエディションが無料で公開されるという衝撃の展開を見せてくれました。

もちろん、企業がExpressで済ませてしまうのはマイクロソフトも許せないだろうし、さすがに、使えるメモリは1GBまで、使えるCPUは1つまで、といった感じで「企業の大規模システムには流用できない対策」は施されていますが、そりゃぁそうだよね!としか言いようがなく、マイクロソフトには感謝こそすれ文句など1ミリグラムもない。

いや、大規模でなければ、企業が使う事だって十分可能かも知れませんよ。だから、ハッキリ言って、個人でサーバー立てて何かやるって場合には、オーバーキルとしか言いようが無いほどの環境となります。

■ SQL-Server 2008 Expressの感動■

SQL-Server 2008 Expressは、かなり強化されていた2005と比較しても、ダメ押しと言っていいくらいに決定的な強化ポイントがいくつもあり、使っていて「マジかー」とか「うわスゲェ」という言葉を連発してしまう感じです。

ついに、「ストアドプロシージャやSQL関数のパラメータとして、テーブル型変数が使える」ようになりました!!
これはもう飛び上がって喜ぶくらいのレベルです。
SQL-Serverでは、配列がサポートされていません。これで何度苦労したことか・・・。しかし、テーブル型変数さえパラメータ渡しに使えれば、もう言う事がありません。

SQL-Server 2008では、CREATE TYPEで「型」を定義しておけるんですね。
あらかじめ定義した型を使って、テーブル型変数を定義。
あとは、これを使ってコードを組めばいいわけです。

たとえば、あくまでも私の環境ですが、以下のようにテストコードを書いてみました。
データは、OpenOfficeのCalcでワークシートを作って用意。
SQL-Serverは、OPENROWSET()関数を使って、ワークシートを直接テーブルと同等に扱う事が可能なんです(SQL-Server 2008は、適切なポリシー設定をしないうちは使用不能になっているので注意が必要ですが)。

USE SPDB;
GO
-- --------------------------
-- テーブル型の登録!
-- --------------------------
CREATE TYPE DEF_GAME AS TABLE
(
GAME_ID int,
GAME_NAME varchar(100),
MANUFACTURER varchar(100),
GENRE varchar(100)
);

-- --------------------------
-- テスト用ストアドプロシージャ作成
-- --------------------------
CREATE PROC SP_TEST
@P1 DEF_GAME READONLY
AS
BEGIN
SET NOCOUNT ON

DECLARE @BASE_DATA DEF_GAME; --変数宣言

--リードオンリーのパラメータを変数に格納
INSERT INTO @BASE_DATA
SELECT * FROM @P1;

--GAME_IDを加工
UPDATE @BASE_DATA
SET GAME_ID = GAME_ID * 1000;

--結果にシーケンス番号を付与して出力
SET NOCOUNT OFF
SELECT
ROW_NUMBER() OVER(ORDER BY GAME_ID) AS "SEQ_NUMBER",
*
FROM @BASE_DATA
ORDER BY GAME_ID DESC;
END;

-- --------------------------
-- データの用意
-- --------------------------
IF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE id=OBJECT_ID('tempdb.dbo.#T_GAME'))
BEGIN
DROP TABLE #T_GAME
END;
SELECT M.*
INTO #T_GAME
FROM OPENROWSET(
'Microsoft.JET.OLEDB.4.0',
'Excel 8.0;HDR=YES;IMEX=1;DataBase=M:\データ\MY_DATA\ゲーム\GAME_DATA.xls',
'SELECT * FROM [GAME$]'
) AS M;

IF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE id=OBJECT_ID('tempdb.dbo.#T_NAME'))
BEGIN
DROP TABLE #T_NAME
END;
SELECT M.*
INTO #T_NAME
FROM OPENROWSET(
'Microsoft.JET.OLEDB.4.0',
'Excel 8.0;HDR=YES;IMEX=1;DataBase=M:\データ\MY_DATA\ゲーム\GAME_DATA.xls',
'SELECT * FROM [NAME$]'
) AS M;

-- --------------------------
-- テーブル変数の定義
-- --------------------------
DECLARE @TBL_GAME DEF_GAME;

-- --------------------------
-- テーブル変数に用意したデータセット
-- --------------------------
INSERT INTO @TBL_GAME
SELECT
M.GAME_ID AS "GAME_ID",
M.GAME_NAME AS "GAME_NAME",
T1.NAME AS "MANUFACTURER",
T2.NAME AS "GENRE"
FROM #T_GAME AS M
INNER JOIN #T_NAME AS T1
ON(M.MANUFACTURER = T1.KEY_ID)
INNER JOIN #T_NAME AS T2
ON(M.GENRE = T2.KEY_ID)
WHERE T1.BUNRUI=1
AND T2.BUNRUI=2
ORDER BY M.GAME_ID;

-- --------------------------
-- ストアドプロシージャにテーブル変数を引き渡し!!
-- --------------------------
EXEC SP_TEST @TBL_GAME;


テーブル型変数をパラメータとして渡せた瞬間は、大げさでも何でもなく「感動」の一言
これは、今までのコードの組み方そのものを変えなくてはならないな、という感触です。

もちろん、管理ツールのManagement Studio 2008 Expressも感動に加速がついてます
は、2005 Expressでは省かれていたようなポイントも盛り込み、まるで製品版であるかのような感覚。特に、32ビット限定であるものの、データのインポートとエクスポートツールが付属しているのは驚きました。
ここまでのものを、無料で公開してしまっていいのだろうか・・・何かあるんじゃないのかと逆に心配になってしまうくらいのレベル

■ありがとうマイクロソフト■

もちろん、マイクロソフトも本当は無料版なんて冗談じゃねーよとか思ってるはずです。
おそらく、LinuxとOracleの強力なコンビネーションを牽制するために、シブシブとやってる事だとは思います。
しかし動機は問題ではなく、本当にありがたいです。感謝の一言。