使用ADO.NET调用存储过程传表值参数时遇类型冲突错误求助
解决ADO.NET调用存储过程时表值参数类型冲突的问题
兄弟,这个错误我之前踩过坑,本质就是你把两个自定义的表值参数(TVP)类型搞混了——dbo.tvpPurchase和dbo.tvpPurchaseDetail是两种不同的TVP类型,你肯定是在ADO.NET代码里给存储过程的某个TVP参数指定了错误的类型名,或者把对应的数据表传错了位置。
下面给你一步步排查和修复的思路:
1. 先核对存储过程的参数定义
首先打开你的存储过程代码,确认两个TVP参数对应的类型,比如它应该是类似这样的:
CREATE PROCEDURE [dbo].[YourProcedureName] @Purchase dbo.tvpPurchase READONLY, @PurchaseDetail dbo.tvpPurchaseDetail READONLY, @Message NVARCHAR(500) OUTPUT, @Status INT OUTPUT AS BEGIN -- 存储过程逻辑 END
这里要记清楚:第一个TVP参数对应tvpPurchase,第二个对应tvpPurchaseDetail,不能搞反。
2. 检查ADO.NET代码中TVP参数的配置
在你的C#代码里,创建SqlParameter时,必须给每个TVP参数指定正确的TypeName,还要确保传入的DataTable结构和对应的TVP一致。
错误示例(导致你现在的问题)
比如你可能把参数的TypeName写反了:
// 错误:给@Purchase参数指定了tvpPurchaseDetail类型 var purchaseParam = new SqlParameter("@Purchase", SqlDbType.Structured) { TypeName = "dbo.tvpPurchaseDetail", // 这里类型错了! Value = purchaseDataTable }; // 错误:给@PurchaseDetail参数指定了tvpPurchase类型 var detailParam = new SqlParameter("@PurchaseDetail", SqlDbType.Structured) { TypeName = "dbo.tvpPurchase", // 这里也错了! Value = detailDataTable };
正确示例
把TypeName和存储过程的参数类型对应上:
// 正确:@Purchase对应tvpPurchase类型 var purchaseParam = new SqlParameter("@Purchase", SqlDbType.Structured) { TypeName = "dbo.tvpPurchase", Value = purchaseDataTable }; // 正确:@PurchaseDetail对应tvpPurchaseDetail类型 var detailParam = new SqlParameter("@PurchaseDetail", SqlDbType.Structured) { TypeName = "dbo.tvpPurchaseDetail", Value = detailDataTable };
3. 额外检查:DataTable结构是否匹配TVP定义
如果上面的TypeName改对了还是报错,那就要检查你的DataTable的列名、数据类型是否和对应的TVP完全一致。比如tvpPurchase有PurchaseId、PurchaseDate列,你的purchaseDataTable也必须有相同名称和类型的列,不能少列或者类型不匹配。
最后,把这些地方修正后,再运行代码应该就能解决这个类型冲突的错误了。
内容的提问来源于stack exchange,提问作者Walif




