読者です 読者をやめる 読者になる 読者になる
ようこそ。睡眠不足なプログラマのチラ裏です。

F#でSQL CLRしちゃうことは一応可能なんだけど、正式にはサポートはされていないのね。そりゃそうだよね。

プログラミング F#2.0 F# SQL Server2005 SQL Server2008 SQL CLR 息抜き

追記あり


なんとなく気が向いたので少しだけ。



主な環境

Windows 7 Home Premium
・SQL Server2008
・F#2.0


まずはclr enabledの変更

まず、SQL Server2008の構成オプションの 'clr enabled' を 0 から 1 に変更してSQL CLRを利用可能にします。
その後、RECONFIGURE ステートメントを実行して設定を反映させます。

sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO


TRUSTWORTHYで無理やり信頼させます。素人にはおすすめできない

この設定で、Server インスタンスがデータベースとその内容を信頼するようにします。
つまり、この設定をすることでセキュリティが弱まります。詳細については「CLR 統合のセキュリティ」あたりを調べてください。

ALTER DATABASE fsharp SET TRUSTWORTHY ON
GO
USE [fsharp]
GO


SQL Serverに必要なアセンブリを登録します。

まずは、F#なアセンブリを動かせるようにFsharp.Core.dllをDBに登録します。
permission_set は unsafe(無制限)でアセンブリを登録します。
この設定では悪意のあるアセンブリから守られません。セキュリティ的にはもっとも危険な状態です。
(ファイルパスとかは適当に自分の環境にあわせましょう)

CREATE ASSEMBLY [FSharp.Core] FROM 'C:\Program Files (x86)\FSharp-2.0.0.0\bin\FSharp.Core.dll' WITH permission_set = unsafe
GO


メッセージ

警告: 登録中の Microsoft .NET Framework アセンブリ 'fsharp.core, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=msil.' は、SQL Server がホストする環境で完全にはテストされていないため、サポートされません。今後このアセンブリまたは .NET Framework をアップグレードしたり、サービスを提供したりする場合、使用中の CLR 統合ルーチンが機能を停止する可能性があります。詳細については、SQL Server オンライン ブックを参照してください。


はい。怒られました。(登録そのものは通ります。)
正式にはサポートはされていないのね。そりゃそうか。今じゃあオープンソースだしね。
てゆうか・・・。はて、これ正式サポートされる日はくるのでしょうか。
F#のオープンソース化については、割かしネガティブな意見も多いみたいだけど、まぁいろんな考え方がありますよね。
難しいことはよくわかりませんが、これでよかったんじゃないかな。より良質なF#コードに出会える機会が増えそうだし。



続いて、SQL CLRで利用するための適当なF#コードを用意します。今回は芸のないHelloなストアドプロシージャです。
大人の事情により、.NET Framework3.5をターゲットとしてビルドします。

namespace SQLCLR
open System
open System.Data
open System.Data.Sql
open System.Data.SqlTypes
open Microsoft.SqlServer.Server

module public Test =
  [<SqlProcedure>]
  let Hello() =
     SqlContext.Pipe.Send("Hello, SQL CLR in F#!")

さっそく登録してみます。
permission_set は external_access(外部アクセス)でアセンブリを登録します。
この設定では、ある程度のセキュリティが保たれています。
(ファイルパスとかは適当に自分の環境にあわせましょう)

CREATE ASSEMBLY Library1 FROM 'C:\Code\F#\SQL CLRとF#\Library1\bin\Release\Library1.dll' WITH permission_set = external_access
GO


なお、SQL Server 2005 および SQL Server 2008では、SQL CLR アセンブリがバージョン 2.0、3.0、あるいは
3.5 の .NET Framework を対象にしている必要があります。 .NET Framework4をターゲットにしたアセンブリを登録しようとすると、
エラー6218のアセンブリ 'ほにゃらら' の検証に失敗したため、アセンブリ 'ほにゃらら' の CREATE ASSEMBLY が失敗しました。データベースで実行するために、参照元のアセンブリが最新かつ信頼済み (external_access または unsafe の場合) であることを確認してください。CLR Verifier エラー メッセージが存在する場合は、そのメッセージに従います。」的なメッセージが出力されて登録できませんのでご注意ください。



ストアドプロシージャの定義

登録したアセンブリのストアドをCREATEします。
F#コードのnamespaceとmodule名に対応する[SQLCLR.Test]でひとくくりとなっている点にご注意を。
[SQLCLR].[Test]だとエラーになっちゃいますよ。

CREATE PROCEDURE Hello AS EXTERNAL NAME [Library1].[SQLCLR.Test].[Hello]
GO


定義したストアドを実行してみます。ほい。

EXEC Hello


実行結果

Hello, SQL CLR in F#!

わーいできました。ということで、一応F#でもモリモリSQL CLR開発をすることが可能!
ということで、ちょっとだけ夢が広がります。未サポートだけどね。事故っても自己責任だけどね。


ところで・・・、fsc.exeでコンパイルするときのコンパイラオプションに
ターゲットとする.NET Frameworkを指定できるものが提供されていないように思われるのですが・・・。
もしそれが可能なのであれば、「--standalone」オプションと併用することで、
FSharp.Core.dllアセンブリをDBに登録しなくても済みそうなので、この問題を解決できそうな気がするのだけど。いまんとこは無理そう。
逆に、Visual Studio上からのビルドでは対象の.NET Frameworkを指定することができる反面、「--standalone」オプションにあたる指定ができない。
えーなんでー。どうしてー。あんまりだー。


以上、「F#でSQL CLRしちゃうことは一応可能なんだけど、
正式にはサポートはされていないのね。そりゃそうだよね。」でした。
おしマイケル



■追記

いげ太さんが、つぶやきにて疑問にお答えしてくださいました。ありがとうございます。


ということで、


Visual Studioの[プロジェクト デザイナー] - [ビルド] - [その他のフラグ] にて、
「--standalone」オプションを指定してビルドします。


それをunsafe指定でアセンブリ登録

CREATE ASSEMBLY Library1 FROM 'C:\Code\F#\SQL CLRとF#\Library1\bin\Release\Library1.dll' WITH permission_set = unsafe
GO


とすることで、FSharp.Core.dllをSQL Serverアセンブリ登録することなく(エラーを回避して)、
F#でSQL CLRを利用することができるようになります。また、MSBuildでTargetFrameworkVersionを指定し、
「--standalone」オプションを適用するという方法でも可能です。
ただし、この方法を利用することで、直接的な「エラーの回避」にはなりますが、
いずれにせよサポート対象外であることには変わりない点にはご注意を。






そうだよね。Hackばむざい!w
ということで皆さん、うれしはずかし朝帰りうれしたのし大好きなF#ライフを。