5

良い一日をお過ごしください。

この 3 日間について考えていたことについて、あなたのアドバイスが必要です。アンマネージ プラットフォームで記述された COM コンポーネントがあります。コンポーネントには、ある種の機密データを返すメソッドがあり、取得したらすぐに値を保存する必要があります。

必要なのは、UDF を呼び出して COM オブジェクトにアクセスし、値を取得することです。私はこれまでにこれを試しましたが、この例外が発生しています:

メッセージ 6522、レベル 16、状態 2、行 1
ユーザー定義ルーチンまたは集計 "GetRate" の実行中に .NET Framework エラーが発生しました: System.Runtime.InteropServices.COMException: CLSID を持つコンポーネントの COM クラス ファクトリを取得しています {D039A99F- 5D45-42C7-A53C-507913D8C6D6} は次のエラーのために失敗しました:
80040154

System.RuntimeType.CreateInstanceSlow (ブール値の publicOnly、ブール値の fillCache)
で System.RuntimeType.CreateInstanceImpl (ブール値の publicOnly、ブール値の skipVisibilityChecks、ブール値の fillCache) で

UserDefinedFunctions.GetRate (SqlString Source_Currency_Name、SqlString Destination_Currency_Name、SqlMoney Amount、SqlBoolean モード) で System.Activator.CreateInstance (型の種類、ブール値の非パブリック)で

関数が登録された COM コンポーネント (80040154) を参照できないようです。clr アセンブリは無制限として登録されます。「sa」または Windows 統合モードで UDF を呼び出そうとしました。違いはありません。

これは COM コンポーネントを初期化するためのコードで、コードは SQL の外部で正常に動作しています

Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("D039A99F-5D45-42C7-A53C-507913D8C6D6"), true))

とにかくこれを機能させる方法はありますか?いずれにせよ、この COM オブジェクトを呼び出す UDF が必要です。少なくとも、この UDF を介して .NET リモート処理を使用して Windows サービスにアクセスする必要があります。この方法で私を導くすべての提案をいただければ幸いです。

皆さん、ありがとうございました。

4

3 に答える 3

5

一般に、COM と SQL の間のブリッジとして SQL CLR オブジェクトを使用することはお勧めしません。セキュリティから始まり、非常に面倒なリリース手順で終わる可能性のある多くの警告があり、簡単に利用できる場合とそうでない場合がある本番SQLボックスへの物理的なアクセスが必要です。

また、Activator.CreateInstance を使用してから clsid を提供していることにも気付きました。元の投稿では、それが COM clsid であることを暗示しています。SQL CLR で作成された AppDomain から動作する Activator が実際に com clsid のオブジェクトを見つけられるかどうかはわかりません。

私がそれを試す方法:

  • com のマネージド プロキシを作成する
  • 署名されてgacに配置されていることを確認してください
  • SQL CLR からそのマネージド プロキシにアクセスしてみてください

しかし、私はそれが機能するかどうかを真剣に疑っています。リモート処理ソリューションの WCF/WebServices/Remoting や SQL Broker の方が適しているようです。

要するに、実際の .net および sql コードを見ないと、これ以上のことはわかりません。

于 2012-11-29T17:06:04.937 に答える
4

CLRアセンブリをSQLServerにインポートしていると思いますか?もしそうなら、これはプラットフォーム/アーキテクチャの問題である可能性があります。DLLを構築するときに、どのプラットフォームをターゲットにしていますか?

正しいプラットフォーム(x86、x64など)に対してDLLを構築していることを確認してください。

"Any CPU"プロジェクトのプラットフォームを"X86"、プロジェクトのプロパティ、VisualStudioのビルド/プラットフォームのターゲットでからに変更することをお勧めします。

次に、を使用し"DROP ASSEMBLY"、続いて"CREATE ASSEMBLY"、を使用して、正しくビルドされたdllを再インポートします。

また、次の変更を行ったことを確認することもできます。

  1. HKey_Classes_Root / Wow6432Node/CLSIDの下にあるCOMオブジェクトGUIDを見つけます。
  2. 見つかったら、新しいREG_SZ(文字列)値を追加します。名前はAppIDで、データは検索したCOMオブジェクトGUIDと同じである必要があります。
  3. HKey_Classes_Root / Wow6432Node/AppIDの下に新しいキーを追加します。新しいキーは、COMオブジェクトGUIDと同じように呼び出す必要があります。
  4. 追加した新しいキーの下に、新しいREG_SZ(文字列)値を追加し、それをDllSurrogateと呼びます。値は空のままにします。
  5. まだ存在しない場合は、HKey_Local_Machine / Software / Classes/AppIDの下に新しいキーを作成します。
  6. この場合も、新しいキーはCOMオブジェクトのGUIDと同じように呼び出す必要があります。このキーの下に値を追加する必要はありません。

別の解決策は、SQLclrを使用してWCFサービスを呼び出すことです。これを行う方法については、次のガイドを参照してください。

http://www.codeproject.com/Articles/21149/Invoking-a-WCF-Service-from-a-CLR-Trigger

于 2012-11-26T15:26:46.203 に答える
0

sql select * from sys.dm_clr_properties でこのコマンドを実行すると、COM アプリのネット バージョンがリターン コマンドよりも大きく、ネット バージョンがそれ以下である場合にのみ機能します。

于 2013-03-14T10:34:15.483 に答える