在sqlparameter中传递值列表,可能是结构化的。
在sqlparameter中传递值列表,可能是结构化的。
是否可以使用SqlDbCommand和SqlParameter在C#代码中创建类似的东西?
DECLARE @Users TABLE (ID INT) INSERT INTO @Users VALUES (10),(20),(30) SELECT COUNT(*) FROM @Users
我尝试了类似的东西:
1)DataTable创建器:
private static DataTable CreateDataTable(IEnumerableids) { DataTable table = new DataTable(); table.Columns.Add("ID", typeof(int)); foreach (int id in ids) { table.Rows.Add(id); } return table; }
2)添加SqlParameter:
sqlParameters.Add(new SqlParameter() { ParameterName = $"@paramname", SqlDbType = SqlDbType.Structured, Value = table });
3)执行命令(命令是SELECT COUNT(*) FROM @Users),参数是步骤2中的参数列表:
using (SqlCommand cmd = new SqlCommand(command, connection)) { if (parameters != null) cmd.Parameters.AddRange(parameters.ToArray()); SqlDataReader reader = cmd.ExecuteReader(); }
我得到的是:
表类型参数'@Users'必须具有有效的类型名称。
我实际上没有一个真正的表,因此没有可用的类型,我只想要以下内容:
DECLARE @Users TABLE (ID INT)
这可行吗?我想要实现的只是传递一系列的值,这种情况下是一系列的整数。
关于标记为重复:
提供的链接不能解决问题,因为问题不是缺少类型名称,而是缺少要使用的类型名称。问题在于我无法创建任何表格,也不能使用任何现有表格来传递TypeName到SqlParameter中。
一个可行的解决方案:
CREATE TYPE [dbo].[IntList] AS TABLE( [Value] [int] NOT NULL )
然后SqlParameter:
sqlParameters.Add(new SqlParameter() { ParameterName = $"@paramname", SqlDbType = SqlDbType.Structured, Value = table, TypeName = "dbo.IntList" });
不过,另一种解决方法是使用GarethD建议的内置类型。我不确定它们在SQL Server 2016中是否可用。
问题的出现原因:
问题的原因是需要在SQL中传递一个值列表作为参数,但是无法直接将值列表作为参数传递给存储过程或查询。
解决方法:
解决方法是使用表类型参数。首先,在SQL中创建一个表类型,然后从C#中传递参数。
具体步骤如下:
1. 在SQL中创建表类型参数。可以使用以下代码创建一个表类型参数,其中"customdatatable"是表类型的名称,"customcolumnname"是表中的列名。
CREATE TYPE customdatatable AS TABLE ( customcolumnname [columnDataType] )
2. 在C#中将DataTable作为存储过程的参数。使用以下代码将DataTable作为存储过程的参数传递给SQL。
DataTable dt = new DataTable(); dt.Columns.Add("customcolumnname"); DataRow dr = dt.NewRow(); dr["customcolumnname"] = "columnvalue"; dt.Rows.Add(dr); SqlParameter[] parCollection = new SqlParameter[1]; parCollection[0] = new SqlParameter("", dt);
通过以上步骤,可以将DataTable作为参数传递给存储过程或查询,从而解决了将值列表作为参数传递的问题。
问题的出现原因是在使用SqlParameter时没有指定TypeName,导致无法正确地将值传递给数据库。解决方法是在SqlParameter中添加TypeName属性,并与数据库中创建的表类型的名称相同。
首先需要在数据库中创建表类型。例如,创建名为"dbo.IntegerList"的表类型,其中包含一个名为"Data"的int类型列。
然后,在代码中使用SqlParameter时,将TypeName属性设置为表类型的名称。这样,就可以将值传递给数据库。
如果没有数据库中的表类型,则需要先创建它。可以使用CREATE TYPE语句在数据库中创建表类型。
以下是解决方法的示例代码:
sqlParameters.Add(new SqlParameter() { ParameterName = $"", SqlDbType = SqlDbType.Structured, Value = table, TypeName = "dbo.IntegerList"; });
通过在SqlParameter中指定TypeName属性,可以正确地将值传递给数据库。
注意,某些情况下在使用SqlCommand.CommandType = CommandType.StoredProcedure时,不需要指定类型名称。但是,在使用CommandType.Text时,必须指定类型名称。
总结一下,如果需要将值作为参数传递给数据库,并且使用了用户定义的表类型,在使用SqlParameter时需要指定TypeName属性。如果没有表类型,则需要先在数据库中创建它。这样,就可以解决问题并正确地将值传递给数据库。