I'm trying to (learn) publish a SQLCLR function using Visual Studio 2017. (It's a simple function that sends an email.)
As a reference I used this articles on CodeProject and MSSQLTips:
Create, Run, Debug and Deploy SQL CLR Function with Visual Studio 2013 Database Project
Send Email from SQL Server Express Using a CLR Stored Procedure
On project properties->SQLCLR I've set:
Permission level : UNSAFE
And according to the article I've updated target databases:
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
And after I've got the error I've followed this advice on MSSQLTips article:
If you get error messages when trying to compile the code you may need to alter the database using the following command and then try again to create the assembly and the stored procedure.
ALTER DATABASE msdb SET trustworthy ON
I've tried using two different target databases:
- SQL-Server 2017 LocalDB
- SQL-Server 2017 Express
I can build the project without errors, but when I publish the project I receive one error when it executes the next command:
CREATE ASSEMBLY [dbSysmac]
AUTHORIZATION [dbo]
FROM 0x5F8A900003000000...
WITH PERMISSION_SET = UNSAFE;
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 10327, Level 14, State 1, Line 1 CREATE ASSEMBLY for assembly 'dbSysmac' failed because assembly 'dbSysmac' is not trusted. The assembly is trusted when either of the following is true: the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission, or the assembly is trusted using sp_add_trusted_assembly.
What I'm doing wrong?
Best Answer
Just to be clear, "clr enabled", and
sp_configure
in general, are instance-level, not database-level configuration.Yikes. Well, that article on MSSQLTips is more of a problem than the error that you are getting. It would be best if you forgot everything you saw in that article and never looked at it again. It is full of bad advice:
SqlString
instead ofString
for input parameter types (and for return types)msdb
? Maybe it's just me, but I would never deploy code tomsdb
(and I would only add code tomaster
if it is physically required, such as when marking a proc as either a start up proc or as a system proc).UNSAFE
permission set? Why? For email? The assembly should beEXTERNAL_ACCESS
. Code (assemblies, logins, users, or anything else) shouldn't be given more permissions than necessary.TRUSTWORTHY ON
formsdb
is two problems in one:TRUSTWORTHY ON
is lazy. Sure, it's fine for doing proof-of-concepts / quick tests, but it is not a good long-term / production-level option. It's a huge security risk. Instead, Module Signing should be used. Here is a guide I wrote for how to accomplish this, and do so within Visual Studio:SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
TRUSTWORTHY
is alreadyON
formsdb
. At least it isON
by default.@body
input parameter should beNVARCHAR(MAX)
, notNVARCHAR(4000)
. This is, after all, HTML email (i.e.myMessage.IsBodyHtml = True
)What database are you actually publishing to? Assuming that you are publishing to another database that is not
msdb
, then you, at least simplistically, in this moment to move forward, need to setTRUSTWORTHY ON
for the DB that you are publishing to. But again, enablingTRUSTWORTHY
is just for testing (please see: PLEASE, Please, please Stop Using Impersonation, TRUSTWORTHY, and Cross-DB Ownership Chaining).Now, if you are executing the
ALTER DATABASE...
manually and then still get the error upon publishing, then most likely you have the "deploy database properties" option selected (in Visual Studio: go to "Project Properties" | "Debug" tab | "Deployment Options" area towards the bottom).TRUSTWORTHY
is one of those database properties. So, when "deploy database properties" is checked, then every deployment will set the options to match what is defined in the project. And by default,Trustworthy
is not enabled.Your options are:
If you are deploying database properties:
To enable
Trustworthy
in Visual Studio (for deployments): go to "Project Properties" | "Project Settings" tab | "Database Settings..." button | "Miscellaneous" tab. Check the box for "Trustworthy" and then click the "OK" button.If you are not deploying database properties:
Enable trustworthy in the database where you are deploying the assembly (enabling
TRUSTWORTHY
inmsdb
won't help)Once you have this working correctly in development, handle security properly before pushing to production:
SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
For learning more about SQLCLR in general, please visit: SQLCLR Info. Be sure to check out the "Stairway to SQLCLR" link, which is a series I am writing on this topic on SQL Server Central.