CREATE ASSEMBLY in SQLCLR using assembly byte string failed because it could not open the physical file

你说的曾经没有我的故事 提交于 2019-12-11 15:24:53

问题


I am trying to add user-defined aggregates to a SQL Server 2008 database whose schema is defined in my Visual Studio 2010 solution file. The code for this custom aggregate lives in a SQLCLR project within the same solution, but I am having a lot of difficulty getting my unit tests to pass. For unit testing this project, I am using a method similar to the one here to get the byte string of the assembly. The test suite or a post-build event needs to automatically update my script to create the assembly each time, because after any sort of MSBuild (from the command line or Visual Studio), the assembly bits change.

The script seems to be updating its assembly bit string to correctly match the current assembly bits for each run. But the unit test still fails, with an underlying SQLException saying, "CREATE ASSEMBLY failed because it could not open the physical file "0xDEADBEEF": 3(The system cannot find the path specified.). (I've removed the real assembly bits from that message.) Why would this error come up when the assembly bits appear to be correct? How should I fix this?

The length of the actual assembly bit string is about 16 KB. Would this be a problem? Does CREATE ASSEMBLY need to have the bits for the whole assembly or just a header, and how would I get only the header?

We already have the unit test infrastructure in place to deploy this database, including running pre- and post-deployment scripts. We also have an authorization set up that our user-defined functions and aggregates need to have.

Here is my post-deployment script:

IF EXISTS (SELECT name FROM sys.assemblies WHERE name = 'foo')
   DROP ASSEMBLY foo
go

-- The assembly bits change after every build from the command line or Visual Studio.  
-- This variable needs to change each time the foo assembly changes.
declare @assemblyBits as varchar(max)
-- This string is really about 15000 characters, including some newlines which are removed
-- in the next block.  Word-wrapping this line or not word-wrapping it seems to have no 
-- effect.
set @assemblyBits = '0x42'

-- Trim whitespace from assembly bits.
declare @sanitizedBits as varchar(max)
set @sanitizedBits = Replace(Replace(Replace(@assemblyBits, Char(10), ''), Char(13), ''), Char(9), '')

CREATE ASSEMBLY foo
AUTHORIZATION bar
from @sanitizedBits 
GO

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'Product')
   DROP AGGREGATE Product
go

CREATE AGGREGATE [Aggregations].[Product]
    (@value float,
    @weight float)
    RETURNS float
    EXTERNAL NAME foo.[foo.Product]
go

回答1:


use dynamic sql if you have the content as a string

    EXEC ('CREATE ASSEMBLY foo AUTHORIZATION bar from ' + @sanitizedBits )

Normally you pass in a varbinary




回答2:


Try executing the Create Assembly code on the remote Server, on which the database is hosted. It should solve the problem.



来源:https://stackoverflow.com/questions/9470150/create-assembly-in-sqlclr-using-assembly-byte-string-failed-because-it-could-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!