Pass table valued parameter using ADO.NET

C#asp.netSqlado.net

C# Problem Overview


How to pass table valued parameter to stored procedure using ADO.NET?

C# Solutions


Solution 1 - C#

  1. Create type in SQL Server:

     CREATE TYPE [dbo].[MyDataType] As Table
     (
     	ID INT,
     	Name NVARCHAR(50)
     )
    
  2. Create Procedure:

     CREATE PROCEDURE [dbo].[MyProcedure]
     (
         @myData As [dbo].[MyDataType] Readonly
     )
     AS
     
     BEGIN
     	SELECT * FROM @myData
     END
    
  3. Create DataTable in C#:

     DataTable myDataTable = new DataTable("MyDataType");
     myDataTable.Columns.Add("Name", typeof(string));
     myDataTable.Columns.Add("Id", typeof(Int32));
     myDataTable.Rows.Add("XYZ", 1);
     myDataTable.Rows.Add("ABC", 2);
    
  4. Create SQL Parameter:

     SqlParameter parameter = new SqlParameter();
     parameter.ParameterName = "@myData";
     parameter.SqlDbType = System.Data.SqlDbType.Structured;
     parameter.Value = myDataTable;
     command.Parameters.Add(parameter); 
    

Solution 2 - C#

I tried this and received the exception:

> The table type parameter '@MyDataType' must have a valid type name.

I had to set the "TypeName" property of the SqlParameter:

parameter.TypeName = "MyDataType";

Solution 3 - C#

This question is a duplicate of https://stackoverflow.com/q/5595353/1414000. Please see that question for an example illustrating the use of either a DataTable or an IEnumerable<SqlDataRecord>.

Solution 4 - C#

For multilinguals, a little late to the show:

a) elsewhere on tsql

--- create a vector data type
CREATE TYPE [dbo].[ItemList] AS TABLE([Item] [varchar](255) NULL)

b)

Dim Invoices As New DataTable("dbo.ItemList") 'table name is irrelevant
Invoices.Columns.Add("Invoice", GetType(String))
...
        With .SqlCommand.Parameters
            .Clear()
            .Add(New Data.SqlClient.SqlParameter() With {
                        .SqlDbType = Data.SqlDbType.Structured,
                        .Direction = Data.ParameterDirection.Input,
                        .ParameterName = "@Invoices",
                        .TypeName = "dbo.ItemList",
                        .Value = Invoices})
        End With
...
   ' using  store procedure
   .CommandText = "SELECT * FROM dbo.rpt(@invoices) "
   ' or direct reference is a select
   .CommandText = "SELECT * FROM dbo.invoicedata" +
   		"where ((select count(*) from @invoices) = 0 or "+
             "InvoiceNumber in (select distinct * from @Invoices)) 

Solution 5 - C#

You can prefix with Exec

using( SqlConnection con = new SqlConnection( "Server=.;database=employee;user=sa;password=12345" ) )
    {
        SqlCommand cmd = new SqlCommand( " exec ('drop table '+@tab)" , con );
        cmd.Parameters.AddWithValue( "@tab" ,"Employee" );
        con.Open( );
        cmd.ExecuteNonQuery( );
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNIckView Question on Stackoverflow
Solution 1 - C#Naresh GoradaraView Answer on Stackoverflow
Solution 2 - C#Matthew M.View Answer on Stackoverflow
Solution 3 - C#Ryan PrechelView Answer on Stackoverflow
Solution 4 - C#fcmView Answer on Stackoverflow
Solution 5 - C#UthaiahView Answer on Stackoverflow