无法访问存储过程中的表变量

我以这种方式将数据表从Code传递给存储过程。

DataTable table = CommonFunctions.ToDataTable(request); object[] spParams = new object[1]; spParams[0] = table; DbCommand dbCommand = db.GetStoredProcCommand("OS_UpdateOrgStructureDetails", spParams); 

我试图在存储过程中访问此参数。

 CratePROCEDURE OS_UpdateOrgUnits @table OS_RenameNodeTable READONLY AS BEGIN UPDATE OrgUnit SET DetailName = ut.NewValue FROM @table ut INNER JOIN OrgUnit ou ON ou.OrgUnitID = ut.OrgUnitID END 

但是当调用存储过程时,它会抛出错误。

 The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 1 ("@table"), row 0, column 0: Data type 0xF3 (user-defined table type) has a non-zero length database name specified. Database name is not allowed with a table-valued parameter, only schema name and type name are valid. 

无法解决错误。

由于SqlCommandBuilder.DeriveParameters方法中的错误,表值参数的SqlParameter对象的TypeName属性包含数据库名称(请参阅http://msdn.microsoft.com/en-us/library/system.data.sqlclient .sqlcommandbuilder.deriveparameters.aspx ,注释“表值参数未正确输入”)。

修复此问题,您可以在创建命令后立即添加此通用代码:

 foreach (SqlParameter parameter in dbCommand.Parameters) { if (parameter.SqlDbType != SqlDbType.Structured) { continue; } string name = parameter.TypeName; int index = name.IndexOf("."); if (index == -1) { continue; } name = name.Substring(index + 1); if (name.Contains(".")) { parameter.TypeName = name; } } 

如果您只有一个或两个表参数,则不必遍历所有参数。 我编写了一个函数,并将该参数传递给该函数,以便修复typename。

这是function:

  Private Sub SetTypeNameForTableParameter(ByRef parameter As System.Data.SqlClient.SqlParameter) If parameter.SqlDbType = SqlDbType.Structured Then Dim name As String = parameter.TypeName Dim index As Integer = name.IndexOf(".") If index <> -1 Then name = name.Substring(index + 1) If name.Contains(".") Then parameter.TypeName = name End If End If End If End Sub 

这是我正在调用数据库的代码段:

 'Get Parameters in stored proc Dim cmd As System.Data.Common.DbCommand = db.GetStoredProcCommand("MyStoredProc") db.DiscoverParameters(cmd) 'The first parameter is the return value. Remove it. Dim returnValueParam As Data.Common.DbParameter = cmd.Parameters(0) cmd.Parameters.Remove(returnValueParam) 'Set type name for every table parameter SetTypeNameForTableParameter(cmd.Parameters(1)) 'Assign values to the parameters cmd.Parameters(0).Value = id cmd.Parameters(1).Value = mydatatable 'Execute the command db.ExecuteNonQuery(cmd)