将DataTable作为参数发送到存储过程

时间:2013-01-01 16:35:14

标签: c# stored-procedures .net-2.0 sql-server-2012-express

我正在尝试使用c#,。net 2.0和SQLServer 2012 Express将DataTable发送到存储过程。

这正是我正在做的事情:

        //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不支持向数据库发送DataTable(缺少诸如SqlParameter.TypeName之类的内容),但我仍然不确定因为我没有看到有人明确声称此功能在.net 2.0中不可用

这是真的吗?

如果是这样,是否有另一种方法可以将数据集合发送到数据库?

提前致谢!

2 个答案:

答案 0 :(得分:1)

开箱即用,ADO.NET没有充分理由支持这一点。 DataTable可以占用任意数量的列,这些列可能会也可能不会映射到数据库中的真实表。

如果我理解你想做什么 - 快速将DataTable的内容上传到具有相同结构的预定义真实表格,我建议你调查SQLBulkCopy

来自文档:

  

Microsoft SQL Server包含一个名为的流行命令提示实用程序   bcp用于将数据从一个表移动到另一个表,无论是否在一个表上   服务器或服务器之间。 SqlBulkCopy类允许您编写   提供类似功能的托管代码解决方案。有   将数据加载到SQL Server表的其他方法(INSERT语句,   例如),但SqlBulkCopy提供了显着的性能   优于他们。

     

SqlBulkCopy类可用于仅将数据写入SQL Server   表。但是,数据源不仅限于SQL Server;任何   可以使用数据源,只要数据可以加载到   DataTable实例或使用IDataReader实例读取。

     

批量加载类型的DataTable列时,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/

上有一个例子

答案 1 :(得分:0)

根据我的经验,如果您能够在C#中编译代码,则意味着ADO.Net支持该类型。但是如果在执行代码时失败,那么目标数据库可能不支持它。在您的情况下,您提到[Sql Server 2012 Express],因此它可能不支持它。根据我的理解,[Sql Server 2005]支持表类型,但您必须将数据库兼容模式保持在99以上。我100%肯定它将在2008年工作,因为我已经使用它并广泛使用它来通过存储过程使用[用户定义表类型](又名UDTT)作为参数进行批量更新对于存储过程。同样,您必须保持数据库兼容性大于99,才能使用MERGE命令进行批量更新。

当然你可以使用SQLBulkCopy但不确定它有多可靠,取决于