5

IP アドレスを取得し、それに対してホスト名を返す単純なユーザー定義関数を C# で作成しました。コードは次のとおりです。

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString getname(String ipAddress)
    {
        System.Data.SqlClient.SqlClientPermission pSql = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
        pSql.Assert();

        System.Security.PermissionSet psql1 = new PermissionSet(System.Security.Permissions.PermissionState.Unrestricted);
        psql1.Assert();

        System.Net.DnsPermission psql = new DnsPermission(System.Security.Permissions.PermissionState.Unrestricted);
        psql.Assert();

        System.Security.Permissions.SecurityPermission psql2 = new SecurityPermission(System.Security.Permissions.PermissionState.Unrestricted);
        psql2.Assert();

        IPHostEntry host = Dns.GetHostEntry(ipAddress);
        return new SqlString(host.HostName.ToString());
    }
}

今、私はそれを展開しましたが、SQLでこの関数を次のように呼び出そうとすると、次のように選択されます dbo.getname('10.10.10.10')

次のエラーが返されます。

Msg 6522, Level 16, State 2, Line 7
A .NET Framework error occurred during execution of user-defined routine or aggregate "getname": 
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException: 
   at System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 unrestrictedOverride, Int32 create)
   at System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission cap, StackCrawlMark& stackMark)
   at System.Security.CodeAccessPermission.Assert()
   at UserDefinedFunctions.getname(String ipAddress)

インターネットをクロールしましたが、何も見つかりませんでした。提案してください。

4

1 に答える 1

6

外部アクセス許可セットを使用してアセンブリを作成する必要があります。また、アセンブリが署名されているか、データベースが信頼できるものとして設定され、データベース所有者が外部アクセス アセンブリのアクセス許可を付与されている必要があります。上記のパーミッションとアサート コードは必要ありません。

例えば

using Microsoft.SqlServer.Server;
using System;
using System.Data.SqlTypes;
using System.Net;

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.None)]
    public static SqlString getname(String ipAddress)
    {
        IPHostEntry host = Dns.GetHostEntry(ipAddress);
        return new SqlString(host.HostName);
    }
}

コードを C:\resolve\resolve.cs に保存してコンパイルします...

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:library /out:C:\resolve\resolve.dll C:\resolve\resolve.cs

ローカル インスタンスでない場合は、.dll をサーバーにコピーします。次に、オブジェクトを作成します...

USE [master]
GO
CREATE DATABASE [clr]; 
GO
ALTER AUTHORIZATION ON DATABASE::[clr] TO [sa]; 
GO
ALTER DATABASE [clr] SET TRUSTWORTHY ON; 
GO
USE [clr]; 
GO
CREATE ASSEMBLY [assResolve] FROM 'C:\resolve\resolve.dll' 
WITH PERMISSION_SET=EXTERNAL_ACCESS; 
GO
CREATE FUNCTION [fnGetHostName](@ipAddress nvarchar(255)) RETURNS nvarchar(255) 
AS EXTERNAL NAME [assResolve].[UserDefinedFunctions].[getname]; 
GO
SELECT [dbo].[fnGetHostName](N'8.8.8.8') as [host]; 
GO
USE [master]
于 2015-04-18T17:05:49.107 に答える