c# - 在MS SQL Server 2012中将Oracle.DataAccess注册为SQLCLR程序集时出现问题

标签 c# .net sql-server oracle sqlclr

编辑3.5 (旨在在最后更新中放置下面的第3项,但被忽略了。A。)

查看由于我的问题而导致的程序集注册失败的方法,以及可以从ProcExplorer跟踪中推断出的有限信息,使我对一些事情做出了一些结论。没有解决方案,只有一些推断

1. Microsoft在某些时候希望允许加载Framework 2.0程序集。我做出这样的推论是,如果将它们仅与排除它们的概念绑定(bind)在一起,则通过立即检查程序集的框架元数据,验证可能会失败。失败是与在2008R2中加载4.0程序集相似的-与此相反,它会显示出严重错误和特定错误,请您不要这样做。

2.如果我升级到包含2.0程序集的2008R2数据库,则该程序集将被加载,并且其中的功能将在SQL 2012数据库中触发。因此,非常有能力执行基于2.0的程序集。让它们通过加载程序是窍门-因此,我坚信,发现突然启用CLR中的2.0框架程序集的补丁或SP不会令我感到惊讶。

3. 我相信,通过有意更改或错误,PERMISSION _ SET = UNSAFE所隐含的某些验证语义在SQL2012 中已更改。我的经验使我相信,如果指定了PEVERIFY /MD(不检查诸如非托管指针之类的东西),则SQL Server的CLR Verifier的早期版本执行的功能相当于PERMISSION_SET = UNSAFE,而如果未指定,则等同于PEVERIFY /IL。但是,在我看来,在SQL 2012中,无论UNSAFE权限标志的如何,CLR验证程序都会执行PEVERIFY /IL 。我很想知道是否有人可以验证这个理论*

EDIT2

在继续研究此问题之后,我还没有找到一种解决方案,可以对项目进行改造,以使用Microsoft几年前创建的System.Data.OracleClient提供程序。另外,进一步的研究和电子邮件使我相信,关于SQL 2008R2和SQL 2012之间的程序集验证发生了更改,至少有一个或两个“不包括电池”的通知-这个程序集恰恰指向了这一点。关于SQLCLR程序集注册问题的多篇博客文章导致断言,验证过程没有任何改变,但是在两个数据库之间注册相同的程序集却产生了一个无法解释的问题。我找不到SQLServer如何验证程序集的方法,因此,此刻,我继续在黑暗中继续寻找解决方案……

我们的MS SQL Server数据库中存在一个长期存在的SQLCLR项目,可以对Oracle数据库进行各种关键查询。该项目已经运行了大约六年,已经从SQL 2005中的32位程序集迁移到了MS SQL Server 2008 R2的64位程序集。

尽管MS SQL 2012升级顾问仅指出了有关某些地理类型的SQLCLR迁移的一般性问题,但我还是偷偷摸摸地怀疑这种迁移可能确实有问题。果然,我发现将这个项目迁移到SQL Server 2012时会遇到我所担心的棘手问题。

尝试注册此相同的64位Oracle.DataAccess.dll(2.112.1.0)(现在已经在SQL Server 2008R2(及其祖先)中愉快地生活了一段时间)时,数据库现在建议程序集“验证失败”。 编辑:我一直认为,授予UNSAFE权限的程序集不会通过验证检查。这不正确吗?

错误响应的摘录如下:

[ : Oracle.DataAccess.Client.OracleDatabase::Startup][mdToken=0x6000021][offset 0x00000048][found unmanaged pointer][expected readonly address of value 'Oracle.DataAccess.Client.OpoConValCtx'] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleDatabase::Startup][mdToken=0x6000021][offset 0x00000080][found unmanaged pointer][expected unmanaged pointer] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleDatabase::Startup][mdToken=0x6000021][offset 0x000000E3][found unmanaged pointer][expected readonly address of value 'Oracle.DataAccess.Client.OpoConValCtx'] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleDatabase::Startup][mdToken=0x6000021][offset 0x0000011B][found unmanaged pointer][expected unmanaged pointer] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleDatabase::Shutdown][mdToken=0x6000023][offset 0x0000003C][found unmanaged pointer][expected readonly address of value 'Oracle.DataAccess.Client.OpoConValCtx'] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleDatabase::Shutdown][mdToken=0x6000023][offset 0x00000073][found unmanaged pointer][expected unmanaged pointer] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleTransaction::Commit][mdToken=0x600002f][offset 0x0000008F][found unmanaged pointer][expected readonly address of value 'Oracle.DataAccess.Client.OpoTxnValCtx'] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleTransaction::Commit][mdToken=0x600002f][offset 0x000000A6][found unmanaged pointer][expected unmanaged pointer] Unexpected type on the stack.
[ : Oracle.DataAccess.Client.OracleTransaction::Dispose][mdToken=0x6000034][offset 0x0000001E][found unmanaged pointer][expected Native Int] ...

意识到2012年的SQLCLR现在使用.NET 4.0,我认为也许同一DLL的4.0版可能会解决此问题。因此,我下载了ODAC 12.1.0.1的64位版本,该版本提供了该库的4.0特定版本。仍然看到类似(但不完全相同)的程序集创建/验证失败-特别是关于“无法验证的非托管指针类型”。

然后,我尝试使用Oracle.DataAccess(Oracle.ManagedDataAccess)的托管代码版本,并且该程序集依赖于辅助程序集,该程序集由于不是“纯” PE格式程序集而也导致注册失败(后来的研究使我转向认为它不允许将MSIL和汇编语言混合使用)。因此,对我而言,这意味着永远无法在SQLCLR中加载托管代码版本。

因此,在这一点上,我剩下的问题和答案很少。在2005/2008/2008R2和2012年之间的装配验证中,究竟发生了什么变化,现在将阻止给定装配进行验证?是否可以使用任何选项或解决方案来注册Oracle.DataAccess?失败将使项目重新配置/重新定位为.NET 4.0。从我们的系统中删除此组件将是一个巨大的麻烦,因此,任何解决方案或建议都将不胜感激。

最佳答案

实际上,SQL Server 2012只能与.NET Framework 4.0一起使用。您无法在SQL Server中加载多个版本的CLR。这是设计使然。 SQL Server 2012也不允许再加载混合程序集。
您可以做的是创建一个单独的(web)服务,其中包含当前的.NET 2.0功能。然后从您创建的纯.NET 4.0 CLR程序集调用该服务上的方法。我认为这是您问题最有可能的解决方案。

关于c# - 在MS SQL Server 2012中将Oracle.DataAccess注册为SQLCLR程序集时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22845585/

相关文章:

c# - F# 从文件中读取和分离文本

c# - 使用 Nhibernate.Mapping.Attributes 指定复合键

c# - 使用Linq过滤掉特定元素内容

mysql - 在数据库中创建多大的名称字段?

c# - 转换 ASP.Net Core 中的 Open Id Connect 声明

C# JsonConvertDeserialization 返回空值

c# - 为什么 IDependencyResolver 与 System.Web 紧密耦合?

c# - 为winform应用程序添加web前端

sql-server - 您能解释一下以下代码中 sys.sp_addextendedproperty 的使用吗?

SQL Server 分区。为明年创建新分区