Context.CurrentMiningModel returns null in UDF - c#

I migrated Mining Structures from a 2008 server to a 2012 server. When I try my CLR UDF (which is working fine on SQL server 2008) in a DMX query on the 2012 server, I am getting this error:
Exception has been thrown by the target of an invocation. Object reference not set to an instance of an object.
My original goal was to get the GetNodeDescription(...) method running. While debugging the problem, I could isolate the problem to this UDF which fails on my SQL server 2012
[SafeToPrepare(true)]
public static string test()
{
return Context.CurrentMiningModel.Name;
}
My guess is that CurrentMiningModel is null because the following code works fine
[SafeToPrepare(true)]
public static string testUser()
{
return Context.CurrentConnection.User.Name;
}
Any Idea on how to solve this?
Is somebody out there who can reproduce this?
Thanks.
Jan
UPDATE:
A contact at Microsoft confirmed this behaviour as desired due to a "Metadata-Refactoring" (whatever this means...). However, the website still pends to be updated appropiately.

This is not the ultimate answer but it's a workaround to get Microsoft's GetNodeDescription working (by explicitly providing the mining model):
[SafeToPrepare(true)]
public static string GetNodeDescription(string MiningModel, string nodeUniqueName)
{
if (Context.ExecuteForPrepare)
{
return string.Empty;
}
return Context.MiningModels[MiningModel].GetNodeFromUniqueName(nodeUniqueName).Descript‌​ion;
}

Related

Integration of a c# class library in SQL Server

I am trying to test the functionality of CLR Functions in SQL Server 2012. I found a tutorial online on how to basically do this and got it to work on my server.(https://www.skylinetechnologies.com/Blog/Skyline-Blog/March-2013/CLR-Functions-in-SQL-Server-A-Tutorial)
Now, i wanted to create a function that doesnt return a table but a string instead. In my understanding, the SQL Server needs some kind of object to work with, so i tried it with the following test method:
public static class TestSingleValue
{
[SqlFunction(DataAccess = DataAccessKind.None, FillRowMethodName = "MyFillRowMethod", IsDeterministic = true)]
public static SqlChars Test123()
{
SqlChars test = new SqlChars("teststring");
return test;
}
}
On the SQL server, i did the following:
ALTER ASSEMBLY ClassLibrary2 from 'D:\SQL\TestCLR\ClassLibrary2.dll' with Permission_set = SAFE
CREATE FUNCTION TestCLR()
returns nvarchar(max)
AS
EXTERNAL name ClassLibrary2.[CLRTest.TestSingleValue].Test123
GO
Execute TestCLR
The SQL Server throws an error when executing the test method, saying that an "Object reference not set to an instance of an object" and further:
System.NullReferenceException:
System.Data.SqlServer.Internal.ClrLevelContext.GetCurrentContextForLobAccess(>>CClrLobContext* pLobContext)
System.Data.SqlServer.Internal.ClrLevelContext.GetXvarWlobStream(CXVariantBasepxvarSource, XvarLOBStreamInitCode eCode, Int64 lcid, SqlCompareOptions compareOpts, CClrLobContext pLobContext).
Can anyone tell me where i got the concept wrong or maybe provide a link to a good tutorial? I couldnt find one until now. Thanks in advance.
Ok i found the answer myself, the problem is with "nvarchar(max)" as return type. You got to define a length to the nvarchar or use a workaround, then it works just fine.
Related: How to create CLR stored procedure with Nvarchar(max) parameter?

Cannot Debug CLR User Defined Type

I'm trying to debug a CLR User Defined Type in SQL Server 2014 / Visual Studio 2013. I can deploy my UDT to the database and execute the script that calls that UDT in the debugger from within visual studio but it throws an error and doesn't hit my breakpoint. The error happens in the static Parse method on the type.
My DBA thought it might be a permissions issue (preventing me from debugging, not the underlying error) but didn't have time to look into it. Any suggestions on what I need to do to debug my UDT?
The SQL Server is a local instance
Per request, the code of Parse:
public static SqlQueryDescriptor Parse(SqlString s)
{
if (s.IsNull)
return Null;
var queryDescriptor = new JsonSerializer().Deserialize<QueryDescriptor>(s.Value);
//var queryDescriptor = new QueryDescriptor();
SortContext sort = new SortContext();
if (queryDescriptor.Sorts != null)
{
foreach (var sortDescriptor in queryDescriptor.Sorts)
{
sort.AddSort(sortDescriptor.Property, sortDescriptor.Direction);
}
}
return new SqlQueryDescriptor(sort, queryDescriptor.Filters, queryDescriptor.Page);
}
The error is a NRE in the Json deserialization library, I need to debug to figure out why that is happening as I didn't write that library and imported it from the web. Although the break point still doesn't hit even if I don't use the deserializer (commented out line)

Empty exception on calling method

I have following code:
public class A: IContract, ...
{
private B b = new B();
// contract method
public string MethodA(string p1, string p2)
{
Log("Start");
SomeObject obj = CreateObj(p1, p2);
Log("Before Send");
string result = b.SendToExternalSth(obj);
// do sth
return result;
}
}
public class B
{
public string SendToExternalSth(SomeObject obj)
{
Log("BEGIN");
string a, b;
a = proxy.Send(obj);
// do sth
Log("End");
return a;
}
}
After line with Before Send is executed I got System.Exception with empty message, and exception's stack trace is pointing to line with closing } for SendToExternalSth method.
Do you have any ideas why it is happening?
I should mentioned that:
this happening only on production environment (works locally and on test env.),
code is in c# - .net 4.0,
This code is part of soap web services code (MethodA is an soap action and SendToExternalSth method is internal method of some other class) hosted under IIS 7.0,
I am building it with 'any cpu' option,
I am deploying Debug build on production env,
Both production and test envs are 64bit windows 2008 r2 sp1,
.net 4 framework is installed with the same version on both of them,
There is lack of Microsoft .NET Framework 4 Multi-Targeting Pack component on production server, comparing to test env, but currently I am not able to install it there.
Please tell me if some more information is needed to solve this issue, I will be more then happy to provide you it.
I've written some more debugging code and changed compilation option several times. After next deploy to production this error didn't occur. I think that was some compilation issue related to Any CPU option, but this is just wild guess.

SpicIE Hostinstance null

I've been working on an IE9 plugin using the .net4 version of SpicIE. On my development machine, everything works great. While testing on a deployment machine, I keep getting a NullReferenceException when attempting HostInstance.BrowserRef.Navigate(URL). I added some logging and it is being reported as null on both machines, but it works without issue on the dev machine. I know at one time it worked on the deployment one and have no idea what might have broken it.
Relevant code follows:
From the plugin base:
public class KB_Toolbar : SpicIE.Host
{
...
public static KB_Toolbar HostInstance;
public KB_Toolbar() : base()
{
HostInstance = this;
}
public static void OpenURL(string URL)
{
if (HostInstance != null)
HostInstance.BrowserRef.Navigate(URL);
}
}
From the toolbar class:
private void MenuClick(object sender, EventArgs e)
{
var URL = vURL[(int)((ToolStripDropDownItem)sender).Tag];
KB_Toolbar.OpenURL(URL);
}
If I leave the HostInstance != null check there, it does not execute the next line on either machine. If I remove it, it executes with no problem on the dev, and throws a NRE on the deployment. I've tried a number of cheap hacks to work around it with no luck. I can't for the life of me figure out what is going on here, especially that it DOES work on the dev machine WHILE supposedly being null.
Any assistance would be greatly appreciated!
Solved it. The answer was a missing /codebase switch in the regasm command.

unable to deploy sql clr stored procedure (unable to verify metadata)

I am trying to run the CREATE ASSEMBLY command for a SQL CLR (.Net 3.5) assembly on SQL Server 2008. It returns a cryptic error message:
An error occurred while gathering metadata from assembly 'My.Awesome.Assembly' with HRESULT 0x80004005.
Why is it doing this, and how can I fix it without deploying it as UNSAFE?
steps I have done:
Followed all rules in http://msdn.microsoft.com/en-us/library/ms403273.aspx
Used no static fields
Have created 2 other SQL CLR assemblies that deploy just fine
This is what solved the problem for me; for future reference to anyone out there, SQL CLR stuff is very, very picky.
I had a constructor like this:
public MyObject(IEnumerable<T> items)
{
_innerItems = items.ToDictionary(i => i.Key);
}
I changed it to this:
public MyObject(IEnumerable<T> items)
{
_innerItems = new Dictionary<int, T>();
foreach (var item in items)
{
_innerItems.Add(item.Key, item);
}
}
And it was then able to deploy. I then proceeded to pound my head against my desk. Two methods, functionally equivalent; one works, and one has a cryptic deployment error message.

Categories