Error When Creating CLR Function - sql-server

I've created an C# class that contains 2 static method and I successfully created an Assembly in SQL 2005. When I try to create a table-valued function from that Assembly I get the following error:
Msg 6509, Level 16, State 36, Procedure , Line 2
An error occurred while gathering metadata from assembly '' with HRESULT 0x80004005.
We have other CLR functions that are that are with in the same dll and seem to work fine. I tried to emulate what the other functions are doing, but I can't seem to get this function to work.
All the documentation online doesn't seem to help

I had the same problem. I changed the return value in the C# method to IEnumerable insted of DataTable and WALLLLLA.
no problem.
GOOD LUCK
tsadok

Related

Win forms designer not opening a derived form in .NET 6. The Extender Provider failed to return an Extender for this object

Deleting bin and obj folders, cleaning solution, and restarting studio did not help.
Designer does open a base form.
Inherited form (FrmBase) has an empty constructor and no parameters. Some of the derived forms have and some do not have an empty constructor, constructor with or without parameters, the error is the same for all.
FrmBase is in another project.
Update 2022-08-05: when I copy the exact form file with its designer, change the name of the class and it works. 😐 But I don't want to do that for a hundred+ forms in my solution. I also looked at differences in the project file for those forms and there is none.
The Extender Provider failed to return an Extender for this object.
Instances of this error (1)
Hide Call Stack
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.InvisibleEditor..ctor(IServiceProvider serviceProvider, String filePath, IVsHierarchy hierarchy, Boolean needsSave, Boolean needsUndoDisabled)
at Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.TextManagerAdapter.CreateTextPoint(FileCodeModel fileCodeModel, VirtualTreePoint point)
at Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.InternalElements.AbstractCodeElement.get_StartPoint()
at EnvDTE.CodeClass.get_StartPoint()
at Microsoft.DotNet.DesignTools.Client.CodeDom.VsCodeDomProvider.Parser.ProcessClass(CodeClass vsClass, CodeNamespace namespace)
at Microsoft.DotNet.DesignTools.Client.CodeDom.VsCodeDomProvider.Parser.ProcessNamespace(CodeNamespace vsNamespace, CodeCompileUnit compileUnit)
at Microsoft.DotNet.DesignTools.Client.CodeDom.VsCodeDomProvider.Parser.ProcessFileCodeModel(FileCodeModel fileCodeModel, CodeCompileUnit compileUnit)
at Microsoft.DotNet.DesignTools.Client.CodeDom.VsCodeDomProvider.Parser.Parse(TextReader codeStream)
at Microsoft.DotNet.DesignTools.Client.CodeDom.MergedCodeDomProvider.Parser.System.CodeDom.Compiler.ICodeParser.Parse(TextReader stream)
at Microsoft.DotNet.DesignTools.Client.CodeDom.CodeDomSource.get_CompileUnit()
at Microsoft.DotNet.DesignTools.Client.CodeDom.CodeDomManager.GetDeclarations()
at Microsoft.DotNet.DesignTools.Client.Loader.VsDesignerLoader.PerformServerLoad()
at Microsoft.DotNet.DesignTools.Client.Loader.VsDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.DotNet.DesignTools.Client.Loader.VsDesignerLoader.DeferredLoadHandler.PerformLoad()
Help with this error
Could not find an associated help topic for this error. Check Windows Forms Design-Time error list
Forum posts about this error
Search the MSDN Forums for posts related to this error
The problem was that I have another .NET Framework project that has those forms linked from .NET6 project. When I just copy the form to .NET Framework project, the problem is resolved.

msadox28.tlb is not a valid .Net assembly file while registering it

I am developing application with vb.net (2015) and MS Access database. I can work fine with existing database. I have now situation where I need to create database programmatically, for billing purpose. It is the situation where each folder will contain database for company/firm selection.
After searching on the internet / StackOverflow I learned about ADOX. Even got the ready code for it. I applied it in my coding.
Adding reference of Microsoft ADO extend 2.8 and 6.0
Created variable Adx as new Adox.catalog
Then finally wrote Adx.create(olejet provider conn string with data source)
In this step I get an error
COM Class not registered
So I tried to register msadox.dll and msadox28.tlb with regsvr32 and regasm but at that time I get another error:
msadox.dll get registered successfully but error gives in msadox28.tlb
Fail to load -file- becuase it is not a valid .net assembly file
Now I am stuck at this point.
My system is Windows 10 64 bit. I tried to target cpu x86, and any cpu but it didn't work. I got many questions and answer here but didn't understand it.
EDIT:
I tried following connection string and it worked, but it creates old 2000-2003 mdb file. i want to use new access file .accdb
String is :
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\VBProj\Testing\test.mdb;Jet OLEDB:Engine Type=5
EDIT : on 20/9/2021 - MON
First of all Thank you very much #Jimi, your suggestion to use ACE.16 and cleaning solution worked. Thanks a lot
I use the following steps to create MS Access database using ADOX in VB.NET:
Project Menu > Add Reference > COM Section > Select Microsoft ADO Ext. 6.0 for DLL and security
Write connection string at program entry point (form load/sub main) -> Provider=Microsoft.ACE.OLEDB.16.0;Data Source=D:\VBProj\Testing\test.accdb, assign it to variable connString
Declare adox catalog globally like Public gAdxCat As New ADOX.Catalog
Use its method gAdxCat.create(connString)
That's all - DONE
Again thanks to #jimi
This is the answer to my question (helped by #jimi)
following are the steps to create msaccess database using ADOX in VB.NET and error occurs mention in original questions.
1-Project Menu > Add Reference > COM Section > Select Microsoft ADO Ext. 6.0 for DLL and security (remove ref of 2.8)
2-write connection string at program entry point (form load/sub main) -> "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=D:\VBProj\Testing\test.accdb" assign it to variable connString
3-declare adox catalog globally like Public gAdxCat As New ADOX.Catalog
4-User its method gAdxCat.create(connString)
5-Thats all DONE
again thanks to #jimi

Failure to parse a CREATE FUNCTION Sql statement in ANTLR C#

I have noticed that when I pass a (valid) CREATE FUNCTION statement to TSqlParser my listener receives a call to EnterCreate_or_alter_procedure()
I am using the latest versions of TSqlLexer.g4 & TSqlParser.g4.
My output also shows
Exception thrown: 'Antlr4.Runtime.InputMismatchException' in Antlr4.Runtime.dll
line 1:7 mismatched input 'FUNCTION' expecting {'OR', 'PROC', 'PROCEDURE'}
What could be causing this?
I found the issue.
It was a copy-paste error from a previous project in which I was only interested in Stored Procedures, hence, I was passing a StoredProcedure context to the walker, not batch().

Can't correctly setup SQL Server connection in mORMot

I try to setup connection to SQL Server and catch the error
var
GFireDACConnProp : TSQLDBFireDACConnectionProperties;
GFFireDACConn: TSQLDBFireDACConnection;
begin
try
GFireDACConnProp := TSQLDBFireDACConnectionProperties.Create('MSSQL?Server=server','dbname','user','pass');
GFFireDACConn := TSQLDBFireDACConnection.Create(GFireDACConnProp);
// OR I := GFireDACConnProp.Execute('Select * from Station', []);
GFFireDACConn.Connect;
....
Error message:
Project app_.exe raised exception class Exception with message 'Object factory for class {3E9B315B-F456-4175-A864-B2573C4A2101} is
missing. To register it, you can drop component [TFDPhysXXXDriverLink]
into your project'.
What is correct way to connect to SQL Server and expose REST service?
FireDAC is more helpful than some other frameworks in that when things go wrong the exception messages often say how to fix the problem.
So, in your case, given that the message says "you can drop component [TFDPhysXXXDriverLink] into your project" the thing to try first would be to drop the relevant DriverLink component onto your form/datamodule. As you're using Sql Server, the the driver link to choose would be the TFDPhysMSSqlDriverLink, which is on the FireDAC Links tab of the Component Palette.
If you're creating a Console application, obviously there's no form or datamodule to drop the link on. In that case, create it in code:
FDPhysMSSQLDriverLink := TFDPhysMSSQLDriverLink.Create(Nil);
I know its an old thread, but if other come by, it can be fixed just by adding the FireDAC's units to your uses clause e.g.
uses
FireDAC.Phys.MSSQL, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.DApt, FireDAC.Stan.Async; // Not sure if you need them all, FireDAC will ask for them

Why might one function run in SQL Server CLR cause a crash, while working fine in a standalone app?

These two methods below are similar, except one handles null values and the other does not. To handle null values, it uses SqlString type and checks the "get_IsNull" property.
Why might the first one be causing the error "A .NET Framework error occurred during execution of user-defined routine or aggregate "CheckMailingAddress": ." when run inside SQL CLR, while the second one does not?
In particular, the TSQL error is "Msg 10329, Level 16, State 49, Line 1 .Net Framework execution was aborted."
.method public hidebysig static bool CheckMailingAddress(valuetype [System.Data]System.Data.SqlTypes.SqlString param0) cil managed
{
.maxstack 8
L_0000: ldarga.s param0
L_0002: nop
L_0003: nop
L_0004: call instance bool [System.Data]System.Data.SqlTypes.SqlString::get_IsNull()
L_0009: brfalse L_0010
L_000e: ldc.i4.1
L_000f: ret
L_0010: ldarga.s param0
L_0012: nop
L_0013: nop
L_0014: call instance string [System.Data]System.Data.SqlTypes.SqlString::get_Value()
L_0019: call class DatabaseValues.MailingAddress DatabaseValues.MailingAddress::op_Explicit(string)
L_001e: pop
L_001f: ldc.i4.1
L_0020: ret
}
.method public hidebysig static bool CheckMailingAddress(string param0) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call class DatabaseValues.CheckMailingAddress DatabaseValues.CheckMailingAddress::op_Explicit(string)
L_0006: pop
L_0007: ldc.i4.1
L_0008: ret
}
Keep in mind, the MSIL is correct as as far as I know, because both of these methods work when called in a standalone app. It's only when called inside SQL CLR that the first of the two crashes. In the SQL CLR, the function is defined with the "nvarchar(4000)" type, which should play nice with SqlString as far as I know.
I could probably implement the first method using "string" as well and still do the null check, but it uses SqlString to take advantage of the INullable interface properties "IsNull" and "Value", because it's part of a generic code generator where other Sql* types could be used.
SIMPLE PROBLEM SUMMARY:
For those distracted by the MSIL in the method body; ignore it. I recompiled the functions to do nothing at all, and my point is that when "SqlString", rather than "string", is the input type, the CLR blows up and terminates with no error message, and the return value is NULL rather than TRUE.
//Crashes when input parameter is "SqlString"
.method public hidebysig static bool CheckMailingAddress(valuetype [System.Data]System.Data.SqlTypes.SqlString param0) cil managed
{
.maxstack 8
L_001f: ldc.i4.1
L_0020: ret
}
//Doesn't Crash when input parameter is "string"
.method public hidebysig static bool CheckMailingAddress(string param0) cil managed
{
.maxstack 8
L_0007: ldc.i4.1
L_0008: ret
}
I found the source of the problem, and was able to resolve it, but I'm not sure about the details.
At some point I switched my DeployDatabaseAssembly project to target .NET 4.0, and AssemblyBuilder must have generated an assembly that targets .NET 4.0 as well. Switching the project to target .NET 3.5 fixed the problem.
What's funny is the source DLL (database.dll) that contains all my datatypes is still targetting .NET 3.5, and was left that way intentionally because I knew SQL Server only supports CLR 2.0 right now, which effectively makes it incompatible with .NET 4.0, because .NET 4.0 seems to require CLR 4.0. Using ILMerge, I was combining the dynamic assembly containing the generated functions with my existing (.NET 3.5) database.dll. This ultimately resulted in hybrid assembly .NET 4.0 assembly that was mostly based on .NET 3.5 features and classes. It's strange that I was able to get functions to work that used the basic "String" and "int" type parameters, but the SqlString type was causing crashes... obviously because it was being pulled from .NET 4.0 System.Data.dll, since it was referenced as "typeof(SqlString)" in my DeployDatabaseAssembly, which was targetting .NET 4.0. It's just weird how that was crashing without any kind of error message or without any kind of warnings about it being incompatible with the loaded SQL CLR modules.
I wish I knew a way to force AssemblyBuilder running in a .NET 4.0 app to generate an assembly targeting .NET 3.5...
Update: Problem thoroughly solved
I focused on the output of ILMerge and went ahead and switched the DeployDatabaseAssembly back to .NET 4.0. By the way, I use ILMerge as a reference in my project, since it's a .NET assembly.
By setting the ILMerge option like this:
ILMerge merger = new ILMerge();
merger.SetTargetPlatform( "v2", #"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client");
The resulting DLL deploys to SQL Server (as it did before), but it actually runs without errors this time.
Interestingly, if I replace just the "v3.5" in the target platform path with "v4.0" and try to deploy the assembly to SQL Server, then I get a useful error message immediately during deployment "CREATE ASSEMBLY for assembly 'my assembly name' failed because the assembly is built for an unsupported version of the CLR runtime.". It's odd that when I wasn't setting any target platform at all, it would deploy fine, but was crashing without any error message.
This table summarizes the above configuration combinations and results:

Resources