首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TSQL -正在执行CLR权限

TSQL -正在执行CLR权限
EN

Stack Overflow用户
提问于 2010-11-05 18:59:19
回答 3查看 8.9K关注 0票数 4

我从CLR (.net程序集)获得了一个sql过程,执行该过程时会返回一个错误。

代码语言:javascript
运行
复制
Msg 6522, Level 16, State 1, Procedure sp_HelloWorld, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'sp_HelloWorld': 
System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException: 
   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.PermissionSet.Demand()
   at System.Data.Common.DbConnectionOptions.DemandPermission()
   at System.Data.SqlClient.SqlConnection.PermissionDemand()
   at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at HelloWorld.SQLCLR.HelloWorld()

这是我的SQL脚本

代码语言:javascript
运行
复制
go
drop procedure HelloWorld
drop assembly HelloWorld
GO

create assembly HelloWorld from 'F:\HelloWorld.dll'
with permission_set = safe
Go
create procedure sp_HelloWorld
as external name HelloWorld.[HelloWorld.SQLCLR].HelloWorld
go
exec sp_HelloWorld

这是我的类(程序集)

代码语言:javascript
运行
复制
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Security.Permissions;
using System.Data;

namespace HelloWorld
{
    public class SQLCLR
    {
        [Microsoft.SqlServer.Server.SqlProcedure]
        public static void HelloWorld()
        {
            string connectString1 = @"Data Source=localhost;Initial Catalog=ItemData;Integrated Security=True";

            SqlClientPermission permission = new SqlClientPermission(PermissionState.None);
            permission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly);
            permission.PermitOnly();
            SqlConnection sqlcon = new SqlConnection(connectString1);
            sqlcon.Open();
            SqlCommand sqlcmd = new SqlCommand("SELECT Top 1 * FROM ItemData.dbo.Item", sqlcon);
            SqlDataReader reader = sqlcmd.ExecuteReader();
            SqlContext.Pipe.Send(reader);
            sqlcon.Close();
        }
    }
}
EN

回答 3

Stack Overflow用户

发布于 2015-09-02 05:16:49

问题很简单,就是您试图访问程序集中标记为SAFE的外部资源。访问外部资源需要将程序集至少设置为EXTERNAL_ACCESS (在某些情况下为UNSAFE)。但是,查看您的代码,您只是尝试连接到本地实例,在这种情况下,有一种更容易(也更快)的方法来实现这一点:使用"Context Connection = true;"作为ConnectionString。

上下文连接是到当前进程/会话的直接连接,它有时被称为进程内连接。使用上下文连接的好处是:

可以在标记为SAFE

  • access到本地临时对象的程序集中执行启动开销(临时表和临时过程,两者的名称都以单个连接开头,而不是双##)

  • access到#SET CONTEXT_INFO连接启动开销

另外:

无论您使用的是进程内连接、上下文连接还是常规/外部连接,都不需要使用SqlClientPermission

  • you正式请求权限。
  • 应该始终通过调用自己的Dispose()方法来清理外部资源。并不是所有的对象都有这个功能,但是SqlConnectionSqlCommandSqlDataReader肯定有。人们通常将可处置对象包装在using()块中,因为它是一个编译器宏,它扩展为try / finally结构,调用finally中的Dispose()方法以确保即使发生错误也能调用它。
  • 许多/大多数可处置对象的Dispose()方法会自动处理对Close()的调用,因此您通常不需要显式调用Close()

您的代码应如下所示:

代码语言:javascript
运行
复制
[Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloWorld()
{
  using (SqlConnection sqlcon = new SqlConnection("Context Connection = true;")
  {
    using (SqlCommand sqlcmd = new SqlCommand("SELECT Top 1 * FROM ItemData.dbo.Item",
               sqlcon))
    {
      sqlcon.Open();

      using (SqlDataReader reader = sqlcmd.ExecuteReader())
      {
        SqlContext.Pipe.Send(reader);
      }
    }
  }
}
票数 6
EN

Stack Overflow用户

发布于 2012-06-20 03:33:54

我只是想在这上面加上我的两个感觉。我正在做一些非常类似的事情,并且我得到了同样的错误。这是我发现的,但是b/c我没有这个级别的数据库访问权限,我不能测试它。

最简单的方法是将权限级别设置为External_Access(尽管不推荐使用MSDN来运行

进程)。

SQL Server主机策略级别权限集SQL Server主机策略级别授予程序集的代码访问安全权限集由创建程序集时指定的权限集确定。有三个权限集: SAFE、EXTERNAL_ACCESS和UNSAFE。

在CLR项目的属性页上设置权限级别,数据库选项卡-设置权限级别-外部,设置程序集所有者-dbo,并运行tsql 'ALTER database DataBaseName SET TRUSTWORTHY‘这将使工作完成!- SmtpClient将正常工作...然后正确地使用强名称密钥文件对Assenbly进行签名...

Full Post Here...

票数 0
EN

Stack Overflow用户

发布于 2010-11-08 03:37:25

您是否已将数据库设置为打开Trusrtworth并启用clr?

尝尝这个

代码语言:javascript
运行
复制
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON
GO

我有一个关于如何使用CLR存储过程的here指南,它可能会有所帮助。

票数 -4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4105252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档