无法将System.IO.Compression添加到SQL Server中的受信任程序集

时间:2014-07-18 23:08:01

标签: c# .net sql-server ssms sqlclr

我正在尝试在.NET 4.5中创建一个SQLCLR存储过程,它可以摆弄ZIP文件。显然System.IO.Compression不在SQL Server的批准列表中,但这是我在尝试通过SQL Server Management Studio手动添加时获得的。如果我尝试通过查询执行CREATE ASSEMBLY,也会发生同样的情况。有任何想法吗?为什么这是禁忌?

我也尝试在SSMS中运行此命令:

CREATE ASSEMBLY SystemIOCOMPRESSION
  FROM 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.IO.Compression.dll'
  WITH PERMISSION_SET = EXTERNAL_ACCESS

...结果与我通过SSMS UI尝试的结果相同。

Error prompt from SSMS

2 个答案:

答案 0 :(得分:7)

您正在尝试导入错误的DLL。这是“引用”DLL,而不是实际的“框架”DLL。以下内容将起作用,因为我不仅尝试使用SQL Server 2012,而且还能够导入System.IO.Compression.FileSystem并执行System.IO.Compression.ZipFile.CreateFromDirectory()

  1. 这是必需的,因为您无法从.Net Framework DLL创建ASYMMETRIC KEY

    ALTER DATABASE [{dbname}] SET TRUSTWORTHY ON;
    
  2. 至少你需要这个:

    CREATE ASSEMBLY [System.IO.Compression]
    FROM N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.IO.Compression.dll'
    WITH PERMISSION_SET = EXTERNAL_ACCESS;
    
  3. 如果您想使用ZipFileZipFileExtensions类,则需要这样(不幸的是,这个类需要设置为UNSAFE):< / p>

    CREATE ASSEMBLY [System.IO.Compression.FileSystem]
    FROM N'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.IO.Compression.FileSystem.dll'
    WITH PERMISSION_SET = UNSAFE;
    
  4. 如果不明显,那么调用上述程序集中方法的程序集也需要PERMISSION_SET EXTERNAL_ACCESS

  5. 对于可能没有意识到这一点的人来说,这是完全清楚的:

    1. Zip*类以及System.IO.CompressionSystem.IO.Compression.FileSystem程序集是.Net 4.5的新内容
    2. 您只能在SQL Server 2012和2014(当前版本)中使用.Net 4.0 / 4.5的新项目; SQL Server 2005/2008 / 2008 R2停留在.Net 2.0系列上。

答案 1 :(得分:0)

我知道这是一个老问题,但本周早些时候我正在编写一个SQLCLR函数,这个函数可以在生成报告后由ssrs sql代码调用,将它们打包成zip文件并通过电子邮件发送给他们给用户。

经过一系列的研究和反复试验,使用ssrs web服务界面是更简单,更合理的方法。您根本不必触摸数据库设置即可使用它并执行完全相同的操作。

要使用它,请向ssrs执行服务添加Web引用。你可以找出你need here的哪一个。配置并添加Web引用后,您可以编写C#/ VB代码,以您选择的格式呈现您想要的任何报告,并保存它们或像其他任何字节流一样按照您的意愿执行。在我们的例子中,我们编写了一个查询来获取用户发送的报告列表,使用api将该用户的所有报告呈现为临时文件,压缩这些临时文件,将它们附加到电子邮件中,然后发送电子邮件关闭给用户。

有一个很好的,简单的例子,说明如何使用api here将报表呈现并保存到磁盘。 (以下代码,以防链接死亡)

string historyID = null;
string deviceInfo = null;
// Can be XML, NULL, CSV, IMAGE, PDF, HTML4.0, HTML3.2,
// MHTML, EXCEL, and HTMLOWC
string format = "Excel"; 
Byte[] results;
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
ReportingExec.Warning[] warnings = null;
string[] streamIDs = null;


ReportingExec.ReportExecutionService re = new ReportingExec.ReportExecutionService();
re.Credentials = System.Net.CredentialCache.DefaultCredentials;

ReportingExec.ExecutionInfo ei = re.LoadReport("/directory/ReportName", historyID);

ReportingExec.ParameterValue[] rptParameters = new ReportingExec.ParameterValue[1];

rptParameters[0] = new ReportingExec.ParameterValue();
rptParameters[0].Name = "DateFormatID";
rptParameters[0].Value = "fr-FR";

re.SetExecutionParameters(rptParameters, "en-us");


results = re.Render(
    format, deviceInfo, out extension, out encoding, 
    out mimeType, out warnings, out streamIDs);

FileStream stream = File.Create("C:\\report.xls", results.Length);
stream.Write(results, 0, results.Length);
stream.Close();

有一件事让我感到困惑,那就是在哪里找到上面的各种类型。当您将Web引用添加到项目时,Web引用将在您为Web引用命名的命名空间中引入所有必需的类型。因此,如果您将Web引用命名为FooService,则所有报告类型都将位于命名空间FooService中。所以你可以在那里找到FooService.ParameterValueFooService.ReportExecutionService等。