Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameter of type 'object' in table-valued parameter for sql_variant column

I have a table-valued parameter in SQL Server 2012 defined as:

CREATE TYPE [dbo].[TVP] AS TABLE (
    [Id] [int] NOT NULL,
    [FieldName] [nvarchar](100) NOT NULL,
    [Value] [sql_variant] NOT NULL
)

I call it in C# with code that looks roughly like the following:

var mdItems = new DataTable();
mdItems.Columns.Add("Id", typeof(int));
mdItems.Columns.Add("FieldName", typeof(string));
mdItems.Columns.Add("Value", typeof(object));
mdItems.Rows.Add(new object[] {2, "blah", "value"}); //'value' is usually a string
SqlCommand sqlCommand = conn.CreateCommand();
sqlCommand.CommandText = "[WriteFieldValues]";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("@FieldValues", mdItems);
sqlCommand.ExecuteNonQuery();

I then get the following error from SQL Server on the ExecuteNonQuery call:

The type of column 'Value' is not supported. The type is 'Object'

I found someone who encountered the same problem 3 years ago when it was identified as a known Microsoft bug. The link to the bug is broken, though. Does anyone know if there is updated information on the status of the bug or a potential workaround? As it stands, this bug really kills the value of sql_variant fields.

like image 751
Dan Hermann Avatar asked Jan 03 '13 22:01

Dan Hermann


People also ask

How do you use table valued parameters?

Table-valued parameters are declared by using user-defined table types. You can use table-valued parameters to send multiple rows of data to a Transact-SQL statement or a routine, such as a stored procedure or function, without creating a temporary table or many parameters.

Can we pass table as a parameter to stored procedure in SQL Server?

Table-Valued Parameters aka TVPs are commonly used to pass a table as a parameter into stored procedures or functions. They are helpful in a way, we can use a table as an input to these routines and we can get rid of dealing more complex steps to achieve this process.

How do you pass a table as a parameter in SQL?

Create a user-defined table type that corresponds to the table that you want to populate. Pass the user-defined table to the stored procedure as a parameter. Inside the stored procedure, select the data from the passed parameter and insert it into the table that you want to populate.


1 Answers

This post is many years old now but I hit the same problem and have a solution. If you do not use a DataTable but instead populate a collection of SqlDataRecord then you can set the datatype of the SqlDataRecord to SqlDbType.Variant.

 List<SqlDataRecord> dataTable = new List<SqlDataRecord>();
var dr = new SqlDataRecord(
                            new SqlMetaData("Id", SqlDbType.Int),
                            new SqlMetaData("Value", SqlDbType.Variant));

dr.SetInt32(0, id);
dr.SetValue(1, myObject);

dataTable.Add(dr);

[...]

SqlCommand sqlCommand = new SqlCommand("dbo.MyProc");
var structuredParam = sqlCommand.Parameters.Add("myTableParam", SqlDbType.Structured);
structuredParam.Value = dataTable;
like image 183
ircharlie Avatar answered Sep 28 '22 06:09

ircharlie