There exist some blog posts about how to use F# with SQLCLR in SQL Server that are helpful: http://richardminerich.com/2015/12/a-safer-way-to-use-f-with-sql-clr/, http://thelastexpression.blogspot.com/2012/04/f-agents-and-sqlclr.html, https://rojepp.wordpress.com/2011/08/03/f_on_sqlclr/, Can the F# core libs be SQLCLR-approved? and for the C# approach: http://www.sqlservercentral.com/Authors/Articles/Solomon_Rutzky/294002/
I am wondering/hoping that with the passage of time there is a blog post out there, which I haven't been able to find yet or an answer here, which addresses how to use F# with SQLCLR such that the assembly can be scripted into hex using Visual Studio (or some other tool), like is done with C# deployment (I don't have access to install code on the server except through SQL Server Management Studio), and is at least more safe than using 'trustworthy on' or 'unsafe'. I've written F# and lots of T-SQL before and the prototype I wrote (which now must live in SQL Server) in Common Lisp would map better to F# (and make me happier than using C#).
I'm skeptical of the approach shown in your first link ( http://richardminerich.com/2015/12/a-safer-way-to-use-f-with-sql-clr/ ) as it does not directly show the loading of the FSharp.Core library, hence it is not clear that the author did not have to set
TRUSTWORTHY ON
in order to at least get that part working. What seems highly suspicious is that in Step 5, the Asymmetric Key-based Login is granted the wrong permission:Granting
EXTERNAL ACCESS ASSEMBLY
does not allow for setting an Assembly toUNSAFE
. That requires theUNSAFE ASSEMBLY
permission. It could be a copy / paste error when writing the post, but no proof is shown (i.e. fromsys.databases
) thatTRUSTWORTHY
is currentlyOFF
, or that the author's code wasn't working prior to creating that Login and granting that permission to it.So, I just tried this by installing the most recent build of FSharp.Core – 4.1.2 – and here is what I found:
Confirm that
TRUSTWORTHY
isOFF
(i.e.0
) via:Attempt to load FSharp.Core as
SAFE
, just to see if it works:That receives the following error:
Attempt to load FSharp.Core again, but as
UNSAFE
:That works. But, I didn't set the Database to
TRUSTWORTHY ON
, nor did I create a Login and grant it theEXTERNAL ACCESS ASSEMBLY
permission. Meaning: the violation is probably found via a run-time verification instead of a load-time verification. And I have no way to test beyond this part, but I would expect that an error will occur.If an error does occur regarding the
UNSAFE
Permission Set for this Assembly, then you can handle that without resorting to settingTRUSTWORTHY ON
, but you will need to create a Certificate in master and a Certficate-based Login:IF your Assembly is also required to be marked as
UNSAFE
, then you can create an Asymmetric Key from the DLL inmaster
and then a Key-based Login from that Asymmetric Key, and then grant that Key-based Login theUNSAFE ASSEMBLY
permission. (this assumes that your Assembly is signed -- and protected with a password)Of course, all of the above assumes that you can get the DLL onto the server or at least onto a share that the SQL Server service account has access to, and you did mention wanting to deploy this via hex bytes. That should be possible by doing:
True
and Permission Set toUnsafe
. This will cause the publish process to include the DLL in the build script.CREATE ASSEMBLY
statement for this Assembly since publish scripts are incremental changes. If this is the case, then go to the project properties, and under Project Settings, check the box for Create script (.sql file) (if not already checked). This will cause the build process to always produce a _Create.sql script, and in there will definitely be theCREATE ASSEMBLY
statement for FSharp.Core.CREATE ASSEMBLY [FSharp.Core] FROM 0x...
statement will obviously be used to load the Assembly into the target DB (i.e. where your Assembly is also getting loaded into).That
CREATE ASSEMBLY [FSharp.Core] FROM 0x...
statement will also be your ticket to creating the objects inmaster
as follows:This worked for me on SQL Server 2012, the only difference being I used the file path instead of the hex bytes.