SQLCLR: How to load these dlls to SQL Server 2017? - sql-server

I have a c# application works with MongoDB using MongoDB NET Driver.
The output folder contains this file set:
DnsClient.dll // managed
libsnappy64.dylib
libsnappy64.so
libzstd.dll
libzstd.dylib
libzstd.so
mongocrypt.dll // unmanaged
MongoDB.Bson.dll
MongoDB.Driver.Core.dll
MongoDB.Driver.dll
MongoDB.Libmongocrypt.dll // unmanaged
SharpCompress.dll
snappy32.dll // unmanaged
snappy64.dll// unmanaged
System.Buffers.dll
System.Memory.dll
System.Numerics.Vectors.dll
System.Runtime.CompilerServices.Unsafe.dll
System.Text.Encoding.CodePages.dll
WFMongoDB.exe // my app
WFMongoDB.exe.config
I want to develop my SQLCLR function for work with MongoDB.
Some of files are cross-platform dlls and some are unmanaged dlls.
The question is: is it possible to load these files to SQL Server database for using by my SQLCLR function?

Not all of those DLLs will work. The unmanaged DLLs cannot be loaded into SQL Server under any conditions. If they are not required, then try to do without their functionality.
If they do contain required code, then you might need to keep them as external, make sure they are COM-visible, and then you can call out to them from within SQL Server.

Related

How to avoid manually browsing DLL in Add Reference of Script Task when deploying package on production?

I use EPPlus.dll library for generating Excel files on the fly for attachment and generate mailer in Script Task of SSIS package.
When there is new requirement for change in mailer comes, I do the change in Script Task on my local machine and send the built package file ( .dtsx ) to DBA team for deployment.
Now everytime I have to ask the DBA team to share production server screen with me where I:
Open the file in Visual Studio Data Tools solution
Browse to the dll location
Add Reference to the dll in Script Task.
Then they import the package file in MSDB from where scheduled job references and executes the package.
If I dont do the above step, the Script Task throws error of reference not found.
Error 1 The type or namespace name 'OfficeOpenXml' could not be found
(are you missing a using directive or an assembly reference?)
I overcame challenge of installing DLL inside GAC that is being referenced in Script Task by dynamically loading the assembly as below'
public void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.LoadFrom(System.IO.Path.Combine(strDLLPath, "EPPlus.dll"));
}
But I am, not able to find steps to avoid manually browsing and adding DLL reference. Please help as DBA team is reluctant/ avoids sharing screen.
Alternatively, what is the correct/best practice way to get package file deployed on server in which external dll is used if I dont have direct access to production server.
I don't think there is a direct way to do that from integration services packages, because the only workaround you can do it is - (what you have done using CurrentDomain_AssemblyResolve function) - loading an assembly from a location instead of installing it into GAC.
There are 3 ways for using custom dll's on deployment:
Assigning DLL's to the GAC
Using the AssemblyResolve Function
Copy all Dll's to the sql server DTS Assemblies folder (example for SQL Server 2008: C:\Program Files\Microsoft SQL Server\100\DTS\Binn) and to the .Net framework assemblies folder.
if the problem is to ask for screen sharing, you can create a small installation wizard that copy these dlls to the specific location and ask the dba team to execute it.
Workaround
When searching for this issue, i found an interesting workaround by using a Web Service instead of direct dll, so you can create a web service which contains the methods you are using and add a Web reference instead of a Local assembly
Side Note: i didn't try this approach before, but i am only trying to help
Useful Links & References
SSIS custom DLLs during deployment
How to load an Assembly in a SSIS script task that isn’t in the GAC
SQL Server SSIS Custom DLL Folders
Using Custom DLL's in an SSIS Script Task
SSIS Script Task cant find reference to assembly
Referencing Other Assemblies in Scripting Solutions
Access WebService via SSIS Script Component
Calling a secure webservice in SSIS through script task
Consume Webservice via SSIS Script Component
HOW TO: Write a Simple Web Service by Using Visual C# .NET

Visual Studio Published Project Crashing when trying to access Database files

This is the biggest problem I've had with my project so far. Every time I try to publish it, I get hangups and crashes whenever the project tries to access a database file (which is fairly often).
I have two database objects, both created as part of my Visual Studio project under the main solution, as BUILDERDATA.mdf and CHARACTERS.mdf. When I access them during test builds, everything functions just fine. However, they always fail in the published project.
I get the feeling either they're not exporting correctly, or the act of publishing the project is breaking the connection strings, so I'm hoping someone can help me pinpoint the issue.
Under my project settings, I have a connection set up to each database. They're both Connection Strings, their scope is Application, and the value is this:
Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\BUILDERDATA.mdf;Integrated Security=True;Connect Timeout=30
Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\CHARACTERS.mdf;Integrated Security=True;Connect Timeout=30
Under Project Properties -> Publish -> Application Files, both databases and their log files are set to Data File (Auto) for Publish Status, Required for Download Group, and Include for Hash.
Under my Prerequisites, I have SQL Server 2012 Express LocalDB marked, as well as Microsoft .NET Framework 4. Part of my code uses .NET, so that's required anyway, and I included SQL Server Express so it can access the database files. However, 2012 is the newest version available for me to include, so I'm not sure if there's an issue with that version?
If there's anything else you guys would need to see, please let me know. I just want to get this figured out and fixed so I can have my friends start testing my program. :(

How to create sql Database in installshield express?

I recently developed a winform application with c# and SQL Server 2008 data access. I want to create an "InstallShield express" setup file for it (I don't want to use ClickOnce or Setup And Deployment witch is available in VS). I want to create a db or attach it to SQL server instance after installing SQL Server Express 2008 SP3 (not local db). What is the best way to do this?
Your question is quite vague as you do not explain what kind of “app”, “setup file” or “db” you are using, nor how you “attach it to sql”. In the future, please include these details. However, I can give a general answer.
Create a seed database, that contains the starting data for your application, in your source project.
Add the seed database file to your project/solution file and set its Build Action to “Content”.
Ensure your installer includes project content in the deployment folder (the application folder for WinForms apps).
To open the seed database from your app, use a connection string like Data Source=|DataDirectory|seed.sdf. Do not try to search for your seed file or to set DataDirectory yourself; the installer will set DataDirectory to the directory your content was installed to.
Do not try to write to DataDirectory; it may not be writable by the user who installed it. Repairing the app will overwrite DataDirectory, destroying anything you saved there, as well.
If you need to save data in the database, copy |DataDirectory|seed.sdf to Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), then read and write all data to the copy.
For more information, read my answer to a poster who wrote to |DataDirectory| and therefore kept destroying his user's data.

How to wire up SSDT post-publish command in VS2012 for database project

The goal is to wire up a target or command (e.g. arbitrary executable) to be run after a database project is successfully published from within Visual Studio 2012 user interface using the Publish menu option from the database project context menu (by right-clicking the database project in Solution Explorer and selecting Publish). We have an existing, custom data loader program that bulk loads data from XML files (dumped from master databases) and it would be very convenient to continue using this existing approach. We cannot use the post-deployment SQL file to load data because it will take far too long to load and is difficult to maintain (manual). The data we are loading is a large amount of configuration data that is required by the application and is not the transactional data of the application (which is even larger).
We are currently using Microsoft Visual Studio Ultimate 2012, 11.0.60610.01 Update 3 and SQL Server Data Tools 11.1.30618.1. The database project was created using the database project template in VS2012 (.sqlproj). We are publishing to both SQL Server 2008 R2 and SQL Server 2012. We do know about the SSDT MSBuild targets file that is included in the sqlproj file and its contents. It seems that none of the Deploy or Publish targets defined in this file are executed by VS2012 during a "Publish" command. The Build targets, however, are executed when the project is built from within VS2012.
Here's what we have tried so far with no luck (each item below was attempted one-at-a-time, in isolation):
Wired up the executable command to the PostPublishEvent (similar to the PostBuildEvent).
Wired up the executable command to the PostDeployEvent (similar to the PostBuildEvent).
Wired up a new, custom target that depends on the AfterPublish target that executes the command.
Wired up a new, custom target that depends on the AfterDeploy target that executes the command.
Override the AfterPublish target in the sqlproj file.
Override the AfterDeploy target in the sqlproj file.
Override the SqlPublish target in the sqlproj file.
If I use any of the above "Publish" methods and execute the Publish target using MSBuild, everything works as expected. If I use the "Publish" user interface command in VS2012, the custom command is never executed. If I wire up the custom command to the PostBuildEvent, it runs via MSBuild and VS2012.
It seems that VS2012 is using different means to publish database projects and is not wired into the SSDT MSBuild targets except for the Build target.
Is there a clean way to wire up an arbitrary command that is executed after the "Publish" command, invoked from the VS2012 user interface, completes, ideally, successfully?
I am also aware of this post, Publish data with SSDT?, but this is not an acceptable approach relative to the existing methods used before VS2012.
Thanks!
I've looked into this too.
From what I can tell, when you use Publish... from the VS 2012/2013 context menu, VS is instantiating a SSDT SqlPublishTask directly, rather then using the common system definitions, presumably so they can integrate it into the "Data Tools" window.
Only solution I can think of is to write an extension that provides a (context) menu item, which would allow you to invoke MSBuild with the target of your choice. The Extension SDK reference seems to have everything you need to get started, while the MSBuild API reference can be found on MSDN.
(A quick search revealed no such existing extension.)
Unfortunately, I don't have access to VS Pro, so can't DiM :(.

Calling a .Net Assembly from a SQL Server 2005 Reporting Services report?

I've currently got a set of reports with a number of common functions sitting in code blocks within the .rdl files. This obviously presents a maintainability issue and I as wondering if anyone knew a way for these different reports to share a library of common code?
Ideally I'd like to have a .Net Assembly attached to my Reporting Services project, which all of my reports can access and call functions from. This would save the headache of trying to update and redeploy about 100 reports every time a change needs to be made to a common function.
Any suggestions?
From within Visual Studio in the properties of the report, on the 'References' tab add the details for the assembly that contains the managed code. This code can be called from expressions within reports using the instance name that is specified.
This assembly can either be stored in the GAC or the PrivateAssemblies directory of Visual Studio, and be deployed to the Report Service 'bin' directory on the Reporting Services server. For more information refer to How to use custom assemblies or embedded code in Reporting Services
I had a lot of pain with this so I hope this helps someone. You can get it from the MSDN article but there are a few points below that I think can help speed someone through this a little faster.
Don't forget to add this to your rssrvpolicy.config file:
<CodeGroup class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust"
Name="MyCodeGroup"
Description="Code group for my data processing extension">
<IMembershipCondition class="UrlMembershipCondition"
version="1"
Url="C:\pathtocustomassembly\customassembly.dll"
/>
</CodeGroup>
I forgot to do this and I was hating it for awhile.
Plus don't forget to hit both of the following folders for 2005 with your new dll:
Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies
Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer\bin
Plus don't use log4net with your assembly. I couldn't make it work. Maybe someone can but not me.
Plus if you mess up like I did you won't be able to delete the files until you close Visual Studio.
Plus make your methods shared or static. It's easier.
Create a deployment batch file. Something like:
#ECHO OFF
REM Name: SRSDeploy_Local.bat
REM
REM This batch files copies my custom assembly to my Reporting Services folders.
REM
REM This is the SQL Server 2005 version:
copy "C:\Projects\Common\lib\SCI.Common.SSRSUtils.dll" "C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies"
copy "C:\Projects\Common\lib\SCI.Common.SSRSUtils.dll" "C:\Program Files\Microsoft SQL Server\MSSQL.2\Reporting Services\ReportServer\bin"
Finally, build your report before previewing.
If it builds you're likely on your way.
Except...
You can't deploy it to your production report server because you'll always get the following error:
Error while loading code module
Which is what I'm working on right now.
The following article lists just about all the different ways of calling .Net code from an SSRS report. Extending Microsoft SQL Server 2000 Reporting Services with Custom Code
If all these reports run against the same server, another option to consider would be to use .Net stored procedures in the database to hold your code.
Many thanks guys, I can now call my assembly from my reports.
Supplementary question:
Is there a namespace I can include when I'm creating my assembly that makes it aware of objects in the report designer such as fields and parameters? It'd be really great if I could pass, say, a collection of fields in a strongly-typed way to my assembly.
And the answer: A couple of hours of searching reveals that adding \Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.ReportingServices.ProcessingObjectModel.dll as a reference in my assembly allows me to access the various Reporting Services types, such as Fields and Parameters. Note that in Reporting Services 2008, the namespace changes.
You must deploy to the GAC.
http://www.developerdotstar.com/community/node/333

Resources