Deploying SQL CLR Assemblies as Part of Continuous Integration / Deployment

4 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 4 LinkedIn 0 4 Flares ×

I’ve had to amend a continuous integration / deployment build process recently to include the deployment of SQL CLR assemblies. This was interesting to say the least – there are a few gotchas:

  • You cant ALTER a clr assembly if any functions (in that assembly) signatures change or are removed
  • You cant really drop and recreate an assembly that has schema bound dependencies (like computed columns)
  • Using SQL CREATE / ALTER with a file path is difficult due to permissions (I have to qualify this – it works very well, but for me I don’t want to be messing around with file system permissions whenever I spin up a new deployment environment)
  • You need to be careful if you have have multiple files linked to your assembly in SQL server

One thing I will say is that as much as you might read about the benefits of continuous integration (etc), there are a lot of development teams that don’t source control their databases and are not used to applying best practice in this area. When working with procedural code we tend to apply a lot of constraints to the way we work, but sql databases seem like a free for all! What this leads me to is that in order to have a successful CI setup with sql you must

APPLY CONSTRAINTS TO DATABASE USAGE

What I mean by this is apply some sensible constraints to say, never schema bind anything to CLR assembly functions, or always use synonyms for cross database activity. These are just a couple of ideas, but there doesn’t seem to be any conventional wisdom out there that I can find.

Deploying the Assembly

So the best way I can find to deploy an assembly in this situation is by hex encoding the file and passing it directly into a sql function. I found this GetHexString function on stack overflow which will get the hex string of an assembly:

Using this function, you can get the hex string you need and pass it to some sql to deploy your assembly. There are a few things that you need to be careful to drop any other files associated with your assembly (like pdb files that may have been introduced). I’ve also found that altering the assembly causes the least problems, but doesn’t always work. For this reason I use a function that looks for any associated pdb files and drops them if they exist, then tries to alter the assembly – if it fails it then tries to drop and recreate:

I usually save this sql snippet into source control somewhere within the database section, and pick this up as part of the database deployment – I then feed it into a SqlCommand with the required parameters:

  • @ClrAssemblyHex – the hex from the previous function
  • @ClrAssemblyName – the name of the assembly (without the .dll extension)

This is by no means perfect and could definitely be cleaned up a bit – but it gets the job done most of the time!

Other Issues

The main other issue that I encountered was that in order to drop and recreate the assembly, you need to drop any dependent clr functions, clr stored procs etc beforehand, and then recreate them afterwards. But thats for a different post!

, , ,

The Essential App Marketing Kit
Subscribe To My Newsletter To Get an Entire Chapter From The Book for FREE
Never display this again
4 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 4 LinkedIn 0 4 Flares ×