Friday, March 30, 2012

Problem with calling methods of User Defined Types (udt)

Hello all,

I have scoured the internet looking for the answer to this question, but have come up blank, so I am making my very first post to a help site. Any ideas or solutions would be greatly appreciated.

I am running through some Samples in Sql Server 2005, and I am currently on the part about User Defined Types. I am running the "User-Defined Data Type (UDT) Sample" from this page: http://msdn2.microsoft.com/en-us/library/ms160738.aspx

So I'm using this code for a ComplexNumber type. The code works fine... mostly. I've compiled it and successfully loaded it into Sql Server 2005 (local instance). I can call all the functions like ToString() and what-not, but the problem comes when I try to call the CompareTo() function. If I pass in something other than a ComplexNumber type (such as a string), then the method correctly returns a -1. When I pass in a ComplexNumber type, I get the following error from the query window:

"Operand type clash: ComplexNumber is incompatible with sql_variant"

I am not declaring the variables as type sql_variant. Also, I have tried creating the second ComplexNumber type (that I am comparing it to) right inside the method call, as below:

DECLARE @.c ComplexNumber;
DECLARE @.c2 ComplexNumber;
DECLARE @.myInt int;
DECLARE @.vari sql_variant;
SET @.c = ComplexNumber::Parse('(1, 2i)');
SET @.c2 = ComplexNumber::Parse('(1, 3i)');

All of the following lines get the same error code:
SET myInt = @.c.CompareTo(@.C2);
SET myInt = @.c.CompareTo(ComplexNumber::Parse('(1, 3i)'));
@.vari = @.c;

That last one I just threw in there because I knew it had the same error code. Does anyone know why this is happening and what I can do to fix it? Even hints would be appreciated at this point (although solutions score bigger points!)

Banging my head against my cubicle,
Tim

I am not an expert, but I asked some, and the reply I got was:

"If he's implemented IComparable, the typical signature for CompareTo is:

public int CompareTo(object obj)

.NET object is treated as SQL_VARIANT, however, UDTs aren't compatiable with
SQL_VARIANT.

A better way to write the interface *should be*:

public int CompareTo(ComplexNumber obj)

This violates the IComparable interface, however: it requires object.

Since SQL Server doesn't use ICompareable for indexing, order by, group by,
implementing it is more or less useless. If I need to compare two instances,
I think its better to create a strongly-typed static method on the class
that does exactly that, returning SqlInt16 instead of int.

However, if you need IComparable for other reasons, then you have to live
with wart."

Does this help?

|||Wow, thanks man. All the examples I looked at (from Microsoft, no less) had implemented the IComparable. I had tried overloading the method before,only to find out that SQL Server doesn't support overloaded methods in UDTs. Anyways, since IComparable is useless, I took it out and it worked like a charm.

Thanks again!
Tim|||

I have a problem looks similar but it is little bit different. you are right that sqlserver is not using ICompareable.

but I using Data gridview Control with User defined Types. Problem is while doing sorting on this column it gives exception that Icomparable requires to be implemented. though i have implemented that Interface. but as SQL server is not using that method then who creates that exception. this is not problem with any other column of Datagridview. and i have created that User defined type with native serialization and also made IsByteOrdered to true.

Assembly is sucessfully deployed and i am able to insert and select data in datagridview. only problem while pressing column header of UDT column.

it seems that exception is thrown by sqlserver while comparision. here is the stack trace for exception.

" at System.Data.Common.SqlUdtStorage.CompareValueTo(Int32 recordNo1, Object value)\r\n at System.Data.Common.SqlUdtStorage.Compare(Int32 recordNo1, Int32 recordNo2)\r\n at System.Data.Index.CompareRecords(Int32 record1, Int32 record2)\r\n at System.Data.Index.IndexTree.CompareNode(Int32 record1, Int32 record2)\r\n at System.Data.RBTree`1.RBInsert(Int32 root_id, Int32 x_id, Int32 position)\r\n at System.Data.RBTree`1.Insert(K item)\r\n at System.Data.Index.InitRecords(IFilter filter)\r\n at System.Data.Index..ctor(DataTable table, Int32[] ndexDesc, IndexField[] indexFields, DataViewRowState recordStates, IFilter rowFilter)\r\n at System.Data.DataTable.GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter)\r\n at System.Data.DataView.UpdateIndex(Boolean force, Boolean fireEvent)\r\n at System.Data.DataView.UpdateIndex(Boolean force)\r\n at System.Data.DataView.SetIndex2(String newSort, DataViewRowState newRowStates, DataExpression newRowFilter, Boolean fireEvent)\r\n at System.Data.DataView.SetIndex(String newSort, DataViewRowState newRowStates, DataExpression newRowFilter)\r\n at System.Data.DataView.set_Sort(String value)\r\n at System.Data.DataView.System.ComponentModel.IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)\r\n at System.Windows.Forms.DataGridView.DataGridViewDataConnection.Sort(DataGridViewColumn dataGridViewColumn, ListSortDirection direction)\r\n at System.Windows.Forms.DataGridView.SortInternal(IComparer comparer, DataGridViewColumn dataGridViewColumn, ListSortDirection direction)\r\n at System.Windows.Forms.DataGridView.Sort(DataGridViewColumn dataGridViewColumn, ListSortDirection direction)\r\n at System.Windows.Forms.DataGridView.OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)\r\n at System.Windows.Forms.DataGridView.OnMouseClick(MouseEventArgs e)\r\n at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)\r\n at System.Windows.Forms.Control.WndProc(Message& m)\r\n at System.Windows.Forms.DataGridView.WndProc(Message& m)\r\n at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\r\n at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\r\n at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)\r\n at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)\r\n at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)\r\n at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)\r\n at System.Windows.Forms.Application.Run(Form mainForm)\r\n at testAlarmType.Program.Main() in c:\\Manoj\\CSharp\\Work\\testAlarmType\\testAlarmType\\Program.cs:line 17\r\n at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)\r\n at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)\r\n at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()\r\n at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Threading.ThreadHelper.ThreadStart()"

let me know if any one has any workaround.

Thanks in advance.

|||I have tried to look at this, and while it seems that IComparable is not used by SQL Server 2005 it is used when ordering DataTables, which seems to be an oversight when the requirements for UDTs were written. I write more in this thread.

No comments:

Post a Comment