F# SqlDataProvider, "The type initializer for 'Main' threw an exception.' - sql

I have been attempting to use the SqlProvider type provider on several different databases where I work. In Visual Studio, intellisense for these different DBs (of types MS Access, SQL Server, and an ODBC connection) all work as shown below:
I've even tried it on the Northwind example database:
It does not matter the connection I actually choose, they seem to all result in 2 exceptions when the code is actually run:
System.TypeInitializationException
HResult=0x80131534
Message=The type initializer for 'Main' threw an exception.
Source=SqlProviderTest2
StackTrace:
at Main.main(String[] _arg1) in C:\Users\***\source\repos\SqlProviderTest2\Program.fs:line 29
Inner Exception 1:
TypeInitializationException: The type initializer for '<StartupCode$SqlProviderTest2>.$Main' threw an exception.
Inner Exception 2:
FileLoadException: Could not load file or assembly 'System.Data.OleDb, Version=4.0.1.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
How is it possible that the intellisense can detect the DB but not work when the program is actually run? Is there a common fix for this?
(Using Visual Studio 2019 Professional, if that makes a difference.)

Related

An unhandled exception occurred while processing the request SqlException

When I create a new project (web api) in Visual Studio 2019, I try running the project but I got the following error:
An unhandled exception occurred while processing the request.
SqlException: Invalid object name 'Books'.
Microsoft.Data.SqlClient.SqlCommand+<>c.b__169_0(Task result)
Did you check spelling in SqlDataReader? For me, I was misspelled. If the spelling is correct, any chance are you re-using the same name of an existing environmental variable for a different database on the same SQL Server? If the answer is yes it can be issue too.

Create assembly in SQL

I tried to create assembly:
CREATE ASSEMBLY SendSmsWSI from 'C:\Development\TestStas\SendSmsWSIntegration\SendSmsWSIntegration\SendSmsWSIntegration\bin\Debug\SendSmsWSIntegration.dll' WITH PERMISSION_SET = UNSAFE
And received this error:
Msg 10301, Level 16, State 1, Line 1
Assembly 'SendSmsWSIntegration' references assembly 'system.servicemodel, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089.', which is not present in the current database. SQL Server attempted to locate and automatically load the referenced assembly from the same location where referring assembly came from, but that operation has failed (reason: 2(The system cannot find the file specified.)). Please load the referenced assembly into the current database and retry your request.
Then I tried:
CREATE ASSEMBLY
[System.ServiceModel]
from'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.ServiceModel.dll'with
permission_set = UNSAFE
But here, I have this kind of error:
Msg 6544, Level 16, State 1, Line 12
CREATE ASSEMBLY for assembly 'System.ServiceModel' failed because assembly 'microsoft.visualbasic.activities.compiler' is malformed or not a pure .NET assembly.
Unverifiable PE Header/native stub.
What have I do in order to create the first assembly I mentioned?
Thanks ahead.
You cannot use WCF in SQLCLR. I just tested on my local 2016 CTP3 and it still gives the same error. There's an issue for this, marked as "Won't Fix" here https://connect.microsoft.com/SQLServer/Feedback/Details/809697 - they just provide the link to the official list of supported assemblies:
Microsoft.VisualBasic.dll
Mscorlib.dll
System.Data.dll
System.dll
System.Xml.dll
Microsoft.VisualC.dll
CustomMarshalers.dll
System.Security.dll
System.Web.Services.dll
System.Data.SqlXml.dll
System.Transactions.dll
System.Data.OracleClient.dll
System.Configuration.dll

MQQueueManager Constructor throwing FileNotFoundException

I have the following vb.net code:
Imports IBM.WMQ
[...]
MQEnvironment.Hostname = hostName
MQEnvironment.Port = portNumber
MQEnvironment.Channel = channelName
queueManager = New MQQueueManager(queueManagerName) ' error here
which is throwing the following error:
System.IO.FileNotFoundException occurred
FileName=C:\Users\User\Documents\Visual Studio 2012\Projects\[...]\bin\Debug\mqclient.ini
HResult=-2147024894
Message=Could not find file 'C:\Users\User\Documents\Visual Studio 2012\Projects\[...]\bin\Debug\mqclient.ini'.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
I am not using any ini files in the construction of my queue manager, so does anyone have any idea what's going on - why is it even looking for one, and why in the same directory as the program? I have installed the MQ client, and afaik I have all the environmental variables, etc. set up properly.
Thanks for any help you can give
Is that an unhandled or a first chance exception? Internally, the MQ .net layer will try to read a MQClient.ini but should function quite happily without it. It reads the file for compatibility with the C client, and can handle some of the MQClient.ini stanzas. I would not have expected an absence of such a file to cause problems, but it will try to open it internally. Was that the full callstack, as I'd have expected some MQ libraries on the stack otherwise.

sp_execute_policy Error in SQL, How To Create SQL Facets Policies

I am trying to create a policy in sql that would constrain sproc to a naming convention.
As when someone creates a new sproc they would be forced to prefix the sproc with sp_
Like - sp_MySprocName.
But I am getting the error below when i try to create a new sproc with the correct naming convention.
When I right click on Policy and choose my policy I click on the Evaluate option and everything runs just fine, unlike when I actually create a new sproc I get this error.
Msg 6522, Level 16, State 1, Procedure sp_execute_policy, Line 0
A .NET Framework error occurred during execution of user-defined routine or aggregate "sp_execute_policy":
System.TypeInitializationException: The type initializer for 'Microsoft.SqlServer.Management.Dmf.PolicyEvaluationHelper' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.SqlServer.Diagnostics.STrace, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.
System.IO.FileNotFoundException:
at Microsoft.SqlServer.Management.Dmf.PolicyEvaluationHelper..cctor()
System.TypeInitializationException:
at Microsoft.SqlServer.Management.Dmf.PolicyEvaluationHelper.EvaluateAutomatedPolicy(String policy, SqlXml eventData, Int64& historyId)
at Microsoft.SqlServer.Management.Dmf.PolicyEvaluationWrapper.EvaluateAutomatedPolicy(String policy, SqlXml eventData, Int64& historyId)
What do I need to do to get ride of this error?
I have updated the stored procedures to prefix of proc_. Now they're proc_MyProcedure.
I am still getting the same error.
Any suggestions?
Basically the problem was that microsoft.sqlserver.diadnostics.strace.dll was not installed in the GAC. Furthermore, this file was not on my server, and not on the installation DVDs, so I couldn't install it. I found it on my PC at home, but there was a trick to getting to my work server.
I believe that I've fixed the problem by copying
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.SqlServer.Diagnostics.STrace to C:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSSHell\Common7\IDE

Sql 2005 CLR Integration - Is Dynamic Assembly Loading supported?

I have a static class which loads a .NET assembly dynamically (using Assembly.LoadFile method)
I get the following error message:
Msg 6522, Level 16, State 2, Line 3
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed
.
When I try assign CAS security using this declaration
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
I instead get this exception
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.Security.SecurityException: Request failed.
Note: I have given my SQL Server service account "Full Access" to my dynamic assemly file on disk. I copied my dyamic assembly using syntax:
create Assembly TestAssembly
From 'C:\MyTestAssembly.dll';
--Alter Assembly to copy dynamic assembly file
Alter Assembly TestAssembly add file from 'C:\mydynamicassembly.dll';
After turning TRUSTWORTHY ON and setting PERMISSION_SET = UNSAFE I now get this exception
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.
As the error message states, dynamic assembly loading is completely disallowed by SQL Server - even under unsafe. The only way for Assembly.Load calls to succeed is if the assembly is already loaded in the database via CREATE ASSEMBLY or in the GAC and on the list of supported ("blessed") assemblies. There is another post on this on the sqlclr blog.
I know this is a very old question now, but I have recently found a way to achieve what you want. When you try and using Assembly.Load(...) in a SQL CLR hosted assembly, it will explicitly fail, this is by design, even with PERMISSION_SET = UNSAFE. This is to ensure the stability of the database server.
The technique to loading your dynamic assemblies, is to register them first and then resolve the type using Type.GetType(...) passing in the fully qualified type name (including assembly version information.
Here are the steps:
1.Compile the type, and finalise on disk (i.e. do not create in-memory assemblies). The CompilerResults type will have a CompiledAssembly property and PathToCompiledAssembly property. Use the latter as accessing the CompiledAssembly property will attempt to use Assembly.Load.
2.Using the path, I call a stored procedure from my code (using new SqlConnection("Context Connection = true")) which I pass in the name of the assembly (which I have predetermined) and the compiled assembly path:
CREATE PROCEDURE re.CreateAssembly
#name VARCHAR(100),
#path VARCHAR(1000)
AS
BEGIN
DECLARE #sql NVARCHAR(2000)
SET #sql = N'CREATE ASSEMBLY [' + #name + '] AUTHORIZATION [DatabaseUser] FROM ''' + #path + ''' WITH PERMISSION_SET + SAFE';
EXEC sp_executesql #sql;
END
GO
3.Using your predetermined name, you can use Type.GetType(...), e.g.:
string typeName = "MyCompiledAssembly.MyClass, MyCompiledAssembly, Version=0.0.0.0, Culture=Neutral, PublicKeyToken=null, ProcessorArchitecture=MSIL";
Type type = Type.GetType(typeName);
When the SQLCLR attempts to resolve the type, it should find it, because in step 2 you've already registered the assembly with Sql Server.
I'm guessing you've got the PERMISSION_SET set to SAFE when you did CREATE ASSEMBLY (this will be the default if you didn't specify it). You'll need to change it to EXTERNAL_ACCESS or UNSAFE if you want to do this.
http://msdn.microsoft.com/en-us/library/ms189524.aspx
I was one the developers # Microsoft who worked on SQL-CLR integration, so I may be able to help.
To achieve what you want you need to do two things:
Mark data base as TRUSTWORTHY
Mark assembly as UNSAFE (database must be trustworthy)
The account under which SQL Server runs must have permissions to access the file on the the file system. Often times the file is on a network share but SQL Server is run under local account that has no permission to access network, so this is often a problem. SQL Express in itse default installation does not have rights to C:.
Note that doing all those things has several negative side-effects:
serious security implications - you are effectively ceding control over the instance to the code in unsafe assembly as it can now use raw pointers to access/change anything in the engine.
Stability - you're also ceding stability guarantees for the same reasons.
Portability and disaster recovery - if you database has to move elsewhere for load-balancing or is restored from backup after machine failure you will not have the mydynamicassembly.dll on the new machine.
If at all possible, consider redesigning your app so that all needed assemblies are pre-loaded into the database itself.
[EDIT: if none of the above helps it best to ask on MSDN forums].