【问题标题】:Unable to access table variable in stored procedure无法访问存储过程中的表变量
【发布时间】:2012-03-29 07:45:09
【问题描述】:

我以这种方式将数据表从代码传递到存储过程。

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.

无法解决错误。

【问题讨论】:

标签: c# sql-server-2008 stored-procedures


【解决方案1】:

由于 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;
    }
}

【讨论】:

  • 太棒了..您节省了更多时间..谢谢.. :-)
【解决方案2】:

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

这是函数:

    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)

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多