CLR Function publish.sql file - sql-server

I have a CLR function that I want to deploy with permission_set = unsafe
The assembly is signed with a public/private key file and I've created an assymtric key, created a login using that asymmetric key and given that login the permission for unsafe assemblies
If I want to deploy the assembly can I just execute the .publish.sql found under ./bin/debug be used to deploy the CLR assembly .dll?
Thanks in advance

If you have already set up the perquisite stuff, then I am curious as to why you didn't just attempt to execute that file to see for yourself as that would have answered this question, right? ;-) But yes, those three steps are all you need to do in order to be create (and use) an Assembly marked with PERMISSION_SET = UNSAFE.
Keep in mind that the "publish" script is always incremental. So you shouldn't take it as being a deployment script that will work in all situations. If you have done a build and made no changes, then it won't re-deploy the Assembly, unless there is an option to always drop-recreate the objects (I know there is for the database but don't remember for the Assembly). The "create" script, if you checked the option to generate it, always drops everything and recreates.
And just in case this was implied, the publish scripts generated by SSDT do not, by default, mess with server-level objects that are not part of the project ("part of the project" means that you have imported the master DB into the solution). So the full Create script won't (or at least shouldn't) remove the Login or Asymmetric Key from [master]. But, if needed, there are options for "Do not drop Logins" and/or "Do not drop Asymmetric Keys".
AND, just to mention since this question regards an older version of SQL Server: SQL Server 2017, which was just released, changes the rules a little for deploying Assemblies. The method described in the question will still work as it creates the Asymmetric Key first, but that is now required even for SAFE Assemblies. I describe (in detail) two options for dealing with this that both a) work in all versions back to SQL Server 2012, and b) work with the framework of Visual Studio and SSDT in a fully automated manner:
SQLCLR vs. SQL Server 2017, Part 2: “CLR strict security” – Solution 1
SQLCLR vs. SQL Server 2017, Part 3: “CLR strict security” – Solution 2
That first link (for Solution 1), is an adaptation of the method detailed in the following article that I wrote for SQL Server Central and that does work with SQL Server 2005 - SQL Server 2016:
Stairway to SQLCLR Level 7: Development and Security

Related

Is there no way to use CLR Assembly in Azure SQL?

I'm using since SQL Server 2012 that support CLR Assembly trigger (coded with C#).
But I'm now finding possibility to move Azure SQL but it says CLR Assembly is not supported.
Is it sure that Azure SQL doesn't support CLR Assembly and no way to do it?
Msg 10341, Level 16, State 100, Line 5
Assembly 'MyProject.SQLCLR' cannot be loaded because Azure SQL Database does not support user-defined assemblies. Contact Azure Technical Support if you have questions.
I also found this article but unclear for me.
Does or does not SQL Azure support CLR assemblies?
The fine manual indicates that an sql like:
CREATE ASSEMBLY SomeName
FROM 0x...
WITH PERMISSION_SET = SAFE;
will work; all you have to do is turn your dll into a string of hexadecimal number pairs representing the bytes and put them in where the ... are. The example is at the very bottom of the MSDN doc. It would be important to note though that that doc explicitly states its advice is applicable to Azure SQL Managed Instance which is a relatively recent provision; ensure that is what you have deployed. See this blog for a more in depth discussion

How to develop t-sql in Visual Studio?

We are using Visual Studio 2013 with SSDT mainly for versioning t-sql code, so the sql is being developed on the dev server and then we use schema compare to transfer the scripts into visual studio (and check into Git). Before deployment (which we currently do with schema compare, too) we have to replace database and server references (with [$(database)] etc.). If we change the code in the dev server and compare again, such SQLCMD variables are lost again. (I would expect schema compare to be smart enough to retain the SQLCMD variables but I found no way to accomplish this).
The logical step is to develop sql in visual studio from the start. But so far, it has been hard to convince anybody in the team to do that. One can write sql and execute it in VS, no problem. One can also switch to SQLCMD mode and execute, all right. But when you create e.g. a view in VS, you must write down a create statement and of course this can be executed once but will yield an error when altering the view and executing the create statement again.
So my question is if anybody has some essential tips on how to do database development exclusively in Visual Studio. We were able to get the database references and all that straight, but not the development process.
I've been streamlining local database development and deployment using Visual Studio database projects for a few years now. Here are some tips.
In general...
Use local db instances: Each developer should have their own database instance installed locally. All scripts (tables, views, stored procs, etc.) should be developed in Visual Studio. Create a publish profile for deploying the project to the local db instance.
Use Publish feature: Confusingly Visual Studio provides both a Deploy and a Publish option which ultimately do the same thing. I recommend using just Publish because it's more prominent in the UI and you can create profiles to configure the deployment process for various database instances.
Keep local db up to date: When a developer makes changes in the database project and checks them in to source control then the other developers should check out these changes and republish the project to their local databases.
Create vs. Alter statements
All of your statements should be Create statements. There is no need for Alter statements or existence checks. Everything should be scripted as if you are creating the database objects for the first time. When you deploy or publish, VS will know whether to issue Alter statements for existing objects.
Data
Some ideas:
Script your data as a series of Insert statements. Include them in a post-deployment script in the database project. But this can be tedious and error-prone.
Keep a database backup that includes all of your test data. When setting up a development environment for the first time, create the database from the backup. After you make significant changes to the data, create a new backup and have your devs recreate their databases from the backup. In most cases it's ok if the backup is out of sync with the schema defined in the project -- simply republish the project (make sure to turn off the "Re-create database" setting so that only the differences are published and thus the data is not lost).
There may be 3rd party tools to do this in which case they are worth looking in to.
Create your own solution for deploying data. Mine involved the following and worked really nicely (but required a lot of time and effort!):
All data stored in XML files - 1 file per table - whose structure resembled the table
An executable to read the XML files and generate SQL merge (or insert/update) statements for each row of data and save them to a SQL script
A pre-build event in the database project to run the executable and copy the resulting SQL script to a post-deployment script in the project
Publish the project and the data will be pushed during post-deployment
Test/Production Deployments
Publish feature: You can create publish profiles for your test and production environments. However it will include your pre- and post-deployment scripts, and you won't get the versatility that the other options provide.
dacpacs: Ed Elliott covered them in his answer. Advantages: no need for Visual Studio to deploy, they can be deployed via SQL Management Studio or the command line with sqlpackage.exe, they can be easier to work with than a T-SQL deployment script.
Schema Compare: Schema compare may be good if you can use Visual Studio for your deployments and you like to double check all of the changes being deployed. You can also selectively ignore changes which is useful when you aren't lucky enough to have a development environment that completely mirrors production.
An age-old challenge. We've tried to use the data projects as they were defined through the years, but ran into several problems, including the fact that it seemed that these projects changed with every release of Visual Studio.
Now, we use the data project only to integrate with TFS for work item management and source code control. The way we do it so that we can build sprocs/views in Visual Studio is we write each script using the drop/create pattern. Our scripts also contain security (we made the mistake of using the default schema... if I could go back in time we'd segregate schemas and do schema-based role level security).
For table schema, we do schema compares to/from a versioned template database.
A typical stored proc looks like this:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[sp_MyStoredProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[sp_MyStoredProcedure]
GO
CREATE PROCEDURE [dbo].[sp_MyStoredProcedure]
#MyParameter int
AS
BEGIN
-- Stored Procedure Guts
select 1
END
Good luck... ultimately, it just has to work for your team.
We are currently on the way to move from SSMT to SSDT. I see that we all facing the same problems and it is very strange that there is no good tutorial on the net (at least I haven't found it yet).
First of all about the variables. I think that you need to update to the newest version of SSDT (20015.02) + DacFx. We are using it and we do not have any problems with variables. It also has some new very good features as do not drop some objects on the target if they do not exist in the source.
However we came to solution to use synonyms for all cross database and linked server objects. For example we have table in the AnotherDatabase.dbo.NewTable. We create synonym [dbo].[syn_AnotherDatabase_dbo_NewTable] FOR [$(AnotherDatabase)].[dbo].[NewTable] and use it in the code instead of referencing the other databases. The same with linked servers: CREATE SYNONYM [syn_LinkedDatabase_dbo_NewTable] FOR [$(LinkedServer)].[$(LinkedDatabase)].[dbo].[NewTable].
Now about the development process. We set debug to our dev database in the project properties (later we are going to have separate databases for each developer). Then when you are modifying stored procedures/views/functions/etc... You open the script, change the CREATE to alter and you can work in the same way as you were doing in the SSMT. You can modify the body, execute it, execute queries in that window. However when you finish, you change it back from ALTER to CREATE and save the file.
The problem here is with the objects that does not support ALTER statement. In that case, you need to publish the code first. But in practice you are doing it so not so frequently so I believe that it is not so big deal.
SSDT is mature enough to use it to create your scripts and deploy your changes but you should move away from using the schema compare to doing deployments using sqlpackage.exe
The process looks something like:
-write code in vs/ssdt
-build project which results in a dacpac (either on your machine or ci server)
-deploy dacpac to db instance, using variables if you need to, to bring db's up to date. Use sqlpackage.exe to deploy or generate scripts which can be deployed manually
It should be pretty straight forward, but please ask if you are not sure on anything!
Ed

How can I do version control of Database Schema?

Is there away (Cheap or FLOSS) to do version control of SQL Server 2008 DB schema?
Here is a nice article by Jeff Atwood on database version control
You can use Team edition for database professionals for this purpose
Here is a list of tools that you can purchase which can be used too:
Red Gate SQL Compare from $295.
DB Ghost from $195
SQL Change Manager $995 per instance.
SQL Effects Clarity standard ed. from $139
SQLSourceSafe from $129.
sqlXpress Diff contact for price. :-(
Embarcadero Change Manager contact for price. :-(
Apex SQL Diff from $399
SQL Source Control 2003 from $199
SASSI v2.0 professional from $180
Evorex Source # shareware or $299+ (conflicting reports!)
Edit Just found this post which explains version control through svn: Versioning SQL Server database
Create a database project for the database, in Visual Studio. Check that project into a library system, such as SVN or Team Foundation Server.
In my experience there is no easy option in an enterprise environment.
The three methods below are the main choices (irrespective of tool set used).
1) Dump entire schema into a file and store file in repository
PROS: Easy
CONS: Big file - difficult to manually edit - hard to see what has changed since last version - can't deploy it so would need some mechanism to prepare a DIFF script between Dev and Test/Live systems
2) Dump every database object into a separate file, stored in repository.
PROS: Very easy to see what has changed. Can produce deployment scripts for most objects easily (although some things would still require DIFF script e.g. Column Definition changes)
CONS: Have to run scripts in a certain order - managing that process can be quite difficult.
3) Treat every change as a separate operation with it's own sequentially numbered SQL script.
PROS: Easy for devs to create scripts, same scripts can be run against each platform (in theory)
CONS: Nightmare to manage - ordering can become an issue, very difficult to see what has changed in a release, or when a given object changed.
Having run with all 3 options, I would say that 2 was lovely to work with, but took ages to set up in the first place - getting all the scripts executed in the correct order took ages - and it STILL required use of a Database diff tool to generate scripts for UAT/Live. So I would now recommend a mix between 1 & 2.

Are CLR DLLs mirrored when using SQL Server Mirroring?

I have a SQL Server database (2008) within which I have some CLR DLLs that SQL uses for various things.
Are these DLLs mirrored when I use SQL Mirroring? Our DBA says not, but I find this crazy and cannot find much info on it online.
Is it possible to mirror the CLR DLLs?
CLR Assemblies are stored in the database, and are mirrored as a part of the database. Each database has its own sys.assemblies view, and if you query the master.sys.assemblies DMV, you won't find the assemblies for other databases in the DMV. There are problems that you may encounter with having a database with assemblies in it mirrored. The first being, if you have an External Access or UNSAFE assembly and you used the TRUSTWORTY bit to allow the assembly in your database, this is disabled during the recovery process when you failover, so you have to re-enable it. If you signed the assembly with a certificate you have to create the certificate and login associated with the assembly on the mirrored server manually since this is stored in master, not in the database. The Assembly will be there, and so will your SQL Database Objects, but it may not function. You may also need to change the database owner name as a part of the failover.
http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/03/06/clr-safety-issues-after-database-restore-to-new-server.aspx
If you want to validate what I say above, backup the user database with an assembly on it, and restore it to another server. Your assembly will be a part of the database.
Just to add the obvious point to what Jonathan said: your assemblies have to be deployed in the mirrored application database, not in msdb or some other database.

Database Versioning Using Visual Studio

In the SO podcast episode 54 Jeff talked about using Visual Studio to save all the database objects to individual files. This sounded like just what my team needed to better implement database schema changes into TFS and I told my lead about it. He thinks it's a great idea to.
Unfortunately, so far I've had no luck getting this to work for me. One of my problems is that I don't have SQL Server installed on my local box (dept policy). I'm obviously doing something wrong.
Can someone give me a rundown of the steps or provide a decent link?
Thanks!
1) Create a connection to the database in Server Explorer.
2) Right-click on the connection and select Publish to provider...
3) Next, Script to file, Next, Types of data to publish should be Schema (unless you need some initial data), finish.
4) Add script to the project and check into source control.
He was referring to a project type in VS that supports managing databases, including (if you set it up correctly), versioning your database publishes.
Check out this article on Database Projects in VS
You want to use the GDR 2. (Sometimes called Data Dude)
This allows for a completely offline solution. You don't need to have SQL Server installed on your machine for this to work. (In fact the GDR is the first version that does not care if you have SQL Server installed.)
I use the GDR for my db (a team of 3 devs and 2 testers) and it works GREAT!
Here is a link for the GDR 2 release:
http://blogs.msdn.com/vstsdb/archive/2009/04/21/microsoft-visual-studio-team-system-2008-database-edition-gdr-r2.aspx
And this is a link to the actual bits:
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=bb3ad767-5f69-4db9-b1c9-8f55759846ed
The basic use is to import from an existing DB and server. (You will probably want a server project and 1 or more DB Projects)
You can then make your changes off line. When you are ready to send you changes back to the DB you can delploy (make sure you set up your deploy options first as I think the default is to drop the db and re-deploy). You can also do a Data->Schema Compare in Visual Studio and comapre your project to your database then get a script of changes from the diff output.
It takes a bit of work, but it really allows great source control and is easy once you get the hang of it. (I have my db auto deploy in my night time build twice a week.)
If you're importing an existing database schema, its important to get the right database project. You should likely be using "Database Projects\SQL Server 2005 Wizard".
Visual Studio requires a database connection it can use to create temporary copies of the databases it is working with. It sounds like this is the issue. Do you have SQLExpress on your local box? Use that as the deployment target (server name would be .\sqlexpress if . does not work).
As an alternative, grab update GDR 2 for Visual Studio. Allegedly, it allows one to work with database projects without using a local instance of sql server to deploy temporary working copies of the database.

Resources