将数据表作为参数发送到存储过程
本文关键字:存储过程 参数 数据表 | 更新日期: 2023-09-27 17:50:24
我正在尝试使用c#, .net 2.0和SQLServer 2012 Express发送一个数据表到存储过程。
大致是这样的:
//define the DataTable
var accountIdTable = new DataTable("[dbo].[TypeAccountIdTable]");
//define the column
var dataColumn = new DataColumn {ColumnName = "[ID]", DataType = typeof (Guid)};
//add column to dataTable
accountIdTable.Columns.Add(dataColumn);
//feed it with the unique contact ids
foreach (var uniqueId in uniqueIds)
{
accountIdTable.Rows.Add(uniqueId);
}
using (var sqlCmd = new SqlCommand())
{
//define command details
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = "[dbo].[msp_Get_Many_Profiles]";
sqlCmd.Connection = dbConn; //an open database connection
//define parameter
var sqlParam = new SqlParameter();
sqlParam.ParameterName = "@tvp_account_id_list";
sqlParam.SqlDbType = SqlDbType.Structured;
sqlParam.Value = accountIdTable;
//add parameter to command
sqlCmd.Parameters.Add(sqlParam);
//execute procedure
rResult = sqlCmd.ExecuteReader();
//print results
while (rResult.Read())
{
PrintRowData(rResult);
}
}
但是我得到以下错误:
ArgumentOutOfRangeException: No mapping exists from SqlDbType Structured to a known DbType.
Parameter name: SqlDbType
在进一步调查后(在MSDN, SO和其他地方),似乎。net 2.0不支持向数据库发送数据表(缺少诸如SqlParameter.TypeName
之类的东西),但我仍然不确定,因为我还没有看到任何人明确声称此功能在。net 2.0中不可用
这是真的吗?
如果是这样,是否有其他方法将数据集合发送到数据库?
提前感谢!
开箱即用,ADO。NET不支持这一点是有充分理由的。DataTable可以包含任意数量的列,这些列可能映射到数据库中的实际表,也可能不映射到数据库中的实际表。
如果我理解你想做什么-将数据表的内容快速上传到具有相同结构的预定义的真实表,我建议你研究SQLBulkCopy。
来自文档:
Microsoft SQL Server包含一个流行的命令提示工具,名为BCP用于将数据从一个表移动到另一个表,无论是在单个表上服务器或服务器之间。SqlBulkCopy类允许您编写提供类似功能的托管代码解决方案。有其他加载数据到SQL Server表的方法(INSERT语句,例如),但是SqlBulkCopy提供了显著的性能比他们有优势。
SqlBulkCopy类只能用于向SQL Server写入数据表。但是,数据源并不局限于SQL Server;任何可以使用数据源,只要可以将数据加载到数据表实例或与IDataReader实例一起读取
SqlBulkCopy在批量加载类型为。的数据表列时会失败将SqlDateTime转换为SQL Server列,该列的类型为SQL Server 2008新增日期/时间类型
然而,你可以在以后的版本中定义SQL Server中的表值参数,并使用它在你要求的方法中发送一个表(DateTable)。在http://sqlwithmanoj.wordpress.com/2012/09/10/passing-multipledynamic-values-to-stored-procedures-functions-part4-by-using-tvp/
根据我的经验,如果你能够用c#编译代码,这意味着ADO。Net支持这种类型。但是,如果在执行代码时失败,则目标数据库可能不支持它。在你的情况下,你提到[Sql Server 2012 Express],所以它可能不支持它。根据我的理解,表类型从[Sql Server 2005]开始支持,但你必须保持数据库兼容模式大于99或其他。我100%肯定它将在2008年工作,因为我已经使用它并广泛使用它通过使用[用户定义表类型](又名UDTT)作为存储过程的内参数对存储过程进行批量更新。同样,您必须保持数据库兼容性大于99才能使用MERGE命令进行批量更新。
当然你可以用SQLBulkCopy但不确定它有多可靠,这取决于