首页 文章

问题在MS SQL Server 2012中将Oracle.DataAccess注册为SQLCLR程序集

提问于
浏览
19

EDIT 3.5 (意思是将项目3放在上一次更新中,但忽略了 . 唉......)

看看程序集注册如何解决我的问题并查看我能从ProcExplorer跟踪中推断出的有限信息让我对一些事情做出了一些结论 . 没有解决方案,只有一些推论

1.微软希望在某些时候允许加载Framework 2.0程序集 . 我做出这样的推断是基于如果它们完全受限于排除它们的概念,验证可能会失败并立即检查程序集的框架元数据 . 如果在2008R2中加载4.0程序集也会失败 - 相反的是严厉的和特定的错误,并说Thou Shalt Not Do.

2.如果我执行升级到包含2.0程序集的2008R2数据库,则会加载程序集,并在SQL 2012数据库中触发其中的函数 . 因此,执行基于2.0的程序集的能力非常强 . 让它们通过加载器是诀窍 - 因此强化了我的信念,即发现一个突然在CLR中启用2.0框架组件的补丁或SP并不会让我感到惊讶 .

  1. I believe that, either through deliberate change or bug, some of the validation semantics implied by PERMISSION _ SET = UNSAFE have changed in SQL2012 . 我的经验使我相信SQL Server的CLR Verifier的早期版本在指定 PERMISSION_SET = UNSAFE 时执行了相同的 PEVERIFY /MD (不检查非托管指针之类的东西),而 PEVERIFY /IL 则不是 . 但是,在我看来,在SQL 2012中,CLR Verifier执行UNSAFE权限标志的 PEVERIFY /IL regardless . 我很想知道是否有人可以验证这个理论*

EDIT2

在继续研究这个问题之后,我还没有找到一个解决方案,不能改进项目以使用微软几年前创建的现已弃用的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(及其祖先)中幸福地生活了一段时间,数据库现在建议程序集"fails verification" . Edit: My understanding has always been that an assembly granted UNSAFE permissions does not go through validation checking. Is this not correct?

以下是错误响应的摘录:

[ : 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版可能会解决这个问题 . 所以我下载了64位版本的ODAC 12.1.0.1,它提供了4.0特定版本的库 . 然而,看到了类似(但不完全相同)的程序集创建/验证失败 - 特别是关于“无法验证非托管指针类型” .

然后我尝试使用托管代码版本的Oracle.DataAccess(Oracle.ManagedDataAccess),并且该程序集依赖于一个辅助程序集,由于它不是一个"pure" PE格式程序集而导致注册失败(后续研究让我相信它有一个不允许混合的MSIL和组装) . 因此,对我来说,这意味着托管代码版本永远不会在SQLCLR中加载 .

所以在这一点上,我留下了问题和答案 . 究竟是什么改变了2005/2008 / 2008R2和2012之间的装配验证,现在会阻止给定的装配验证?有没有可行的选择或解决方案让Oracle.DataAccess注册?如果失败将使项目重新配置/重定向到.NET 4.0没有实际意义 . 从我们的系统中删除这个组件将是一个巨大的麻烦,所以任何解决方案或建议将不胜感激 .

1 回答

  • 2

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

相关问题