Is it possible to create something like this in C# code using SqlDbCommand and SqlParameter?
DECLARE @Users TABLE (ID INT)
INSERT INTO @Users
VALUES (10),(20),(30)
SELECT COUNT(*) FROM @Users
I tried something like this:
1) DataTable creator:
private static DataTable CreateDataTable(IEnumerable<int> ids)
{
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
foreach (int id in ids)
{
table.Rows.Add(id);
}
return table;
2) Add SqlParameter:
sqlParameters.Add(new SqlParameter()
{
ParameterName = $"@paramname",
SqlDbType = SqlDbType.Structured,
Value = table
});
3) Execute command (command is SELECT COUNT(*) FROM @Users), parameters is list of parameters from step 2:
using (SqlCommand cmd = new SqlCommand(command, connection))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters.ToArray());
SqlDataReader reader = cmd.ExecuteReader();
What I get is:
The table type parameter '@Users' must have a valid type name.
And I don't really have a real table so no type available, just want it to be:
DECLARE @Users TABLE (ID INT)
Is that doable? What I want to achieve is just pass list of values, in this case list of ints, obviously.
IN REGARD TO MARKED AS DUPLICATE:
Provided link doesn't solve the problem since it's not lack of typename problem but rather lack of typename to use. The problem is that I can't create any table and can't use any existing one to pass TypeName in SqlParameter.
ONE WORKING SOLUTION:
CREATE TYPE [dbo].[IntList] AS TABLE(
[Value] [int] NOT NULL
)
and then SqlParameter:
sqlParameters.Add(new SqlParameter()
{
ParameterName = $"@paramname",
SqlDbType = SqlDbType.Structured,
Value = table,
TypeName = "dbo.IntList"
});
Nevertheless, another step would be to use built-in type like GarethD suggested. I'm not sure if they are available in SQL Server 2016.