2010年4月29日木曜日

SQL-Server 2008 Expressで、テキストを直接ファイルに書き出す関数を作る。(Visual Studio 2010 Expressも使用開始)




今回の記事は、SQL-Server 2008 Expressにおいて、テキストを直接ファイルに書き出す関数を作ってみます。

SQLCLR(C#言語)による関数の開発なんですが、今回より、プログラムの開発に、いよいよVisual Studio 2010 Express (Visual C# 2010 Express)を使ってみました。

まず、大きな注意点なんですが、対象のフレームワークを最新の.NET Framework 4に設定してしまうと、アセンブラのビルド(DLLの作成)そのものは正常に終了するのですが、肝心のSQL-Server 2008 Expressへの登録がうまくいきませんでした。
ひょっとして設定を色々と煮詰めれば良いのかも知れませんが、今回は対象のフレームワークを3.5にしたらうまく行ったので、それで対応することとします。

SQL-Server 2000では到底不可能な事ですが、SQL-Server 2008は、SQLCLRの威力が炸裂。
このように、クエリーから直接テキストファイルを書き出す事が可能です。
今回の関数SQLCLR_WriteText()は、指定したテキストを、一行一行ファイルに書き出します。上書きか追加かはパラメータで指定可能。
書き込み成功すると、書き込んだバイト数をint型で返します。
今回のは、あくまでログファイル作成のような使い方が出来れば良いなぁと思って作りました。
ちなみに文字コードはShift_JIS固定にしてます。

それと、今回ばかりは、Visual Studio 2010 Expressのテストも兼ねています。
なんか、かなり大丈夫そうですね!!

SQLCLRの登録などは過去の記事をご参考になさって下さい

■実行例■

SELECT SPDB.dbo.SQLCLR_WriteText('*** SQL-Server 2008 Expressいいなぁ ***','C:\TEST\TEST.TXT',0);
--0は上書き(新規)モード

SELECT SPDB.dbo.SQLCLR_WriteText('*** VisualStudio 2010 Expressいいなぁ ***','C:\TEST\TEST.TXT',1);
--1は追加モード

SELECT SPDB.dbo.SQLCLR_WriteText('*** Windows 7 (64bit)いいなぁ ***','C:\TEST\TEST.TXT',1);
SELECT SPDB.dbo.SQLCLR_WriteText('*** OpenOffice 3.2いいなぁ ***','C:\TEST\TEST.TXT',1);
SELECT SPDB.dbo.SQLCLR_WriteText('*** Firefox 3.6いいなぁ ***','C:\TEST\TEST.TXT',1);
SELECT SPDB.dbo.SQLCLR_WriteText('*** EOS 7D欲しいなぁ ***','C:\TEST\TEST.TXT',1);


■コード■
(インデントは消えています)
(無償版のVisual C# 2010でプログラムを書いています)

//*******************************************************************************
//* SQL関数
//*******************************************************************************
//------------------------------------
//テキストをファイルに書き出す関数
//------------------------------------
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlInt32 SQLCLR_WriteText(
SqlString p_value,
SqlString p_path,
SqlBoolean p_mode
)
{
//結果格納エリア
Int32 int_result = 0;
//文字コード
Encoding enc_this = Encoding.GetEncoding("Shift_JIS");
//テキスト書き出し用
StreamWriter obj_SW = null;
//上書き・追加用
bool bol_value;
try
{
//書き込みバイト数
int_result = (enc_this.GetBytes((string)p_value)).Length;

if (p_mode.Equals(SqlBoolean.True))
{ //追加モード
bol_value = true;
}
else
{ //上書きモード
bol_value = false;
}
obj_SW = new StreamWriter((string)p_path, bol_value, enc_this);

obj_SW.WriteLine((string)p_value);

}
catch (System.Exception obj_err)
{
throw obj_err;
}
finally
{
if (obj_SW != null)
{
obj_SW.Close();
obj_SW.Dispose();
}
}
return (SqlInt32)int_result;
}


■SQL-Server 2008側の登録■
(環境はご自分のものに読み替えお願いいたします。)

-- .NET Frameworkは3.5が対象となります!!
-- *******************************************************
-- 作成したMY_SQLCLR.DLLをアセンブリ登録する
-- 権限は、外部ファイルを読み書き可能なEXTERNAL ACCESSにする。
-- *******************************************************
USE SPDB
GO
CREATE ASSEMBLY "ASSEMBLY_SQLCLR"
FROM 'C:\Users\morimori\MAIN_WORK\Program\SQLCLR\MY_SQLCLR\MY_SQLCLR\bin\Release\MY_SQLCLR.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS;
GO


-- *******************************************************
-- SQLCLRの関数インターフェース
-- *******************************************************
-- ----------------------------------------------
-- テキストをファイルに書き出す関数
-- (パラメータ説明)
-- @p_value : 書き出したいテキスト
-- @p_path : 書き出したいファイルのフルパス
-- @p_mode : モード(0=上書き,1=追加)
-- ----------------------------------------------
create function SQLCLR_WriteText(
@p_value nvarchar(max),
@p_path nvarchar(max),
@p_mode bit
)
RETURNS int
AS EXTERNAL NAME ASSEMBLY_SQLCLR.CLS_SQLCLR.SQLCLR_WriteText;
GO