2012-03-29 9 views
7

Estoy pasando una tabla de datos desde el código al procedimiento almacenado de esta manera.No se puede acceder a la variable de la tabla en el procedimiento almacenado

DataTable table = CommonFunctions.ToDataTable(request); 
object[] spParams = new object[1]; 
spParams[0] = table; 

DbCommand dbCommand = 
    db.GetStoredProcCommand("OS_UpdateOrgStructureDetails", spParams); 

Estoy tratando de acceder a este parámetro en el procedimiento almacenado.

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 

Pero cuando se realiza una llamada al procedimiento almacenado se produce un error.

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. 

No se ha podido resolver el error.

+0

Esto podría ayudar http://msdn.microsoft. com/en-us/library/bb510489 (SQL.100) .aspx –

Respuesta

15

Debido a un error en el método SqlCommandBuilder.DeriveParameters, la propiedad TypeName del objeto SqlParameter para el parámetro de tabla valorada contiene el nombre de la base de datos (consulte http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommandbuilder.deriveparameters.aspx, el comentario "Parámetros validados de tabla no escritos correctamente").

La solucionar este problema, puede agregar el código de propósito general justo después de la creación de la orden:

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; 
    } 
} 
+1

Agradable. esto funcionó. +1 –

+0

Muy bien. – user960567

+0

Excelente ... Has ahorrado más tiempo ... Gracias ... :-) –

1

Si sólo tiene uno o dos parámetros de la tabla, que no tiene que recorrer todos los parámetros. Escribí una función en su lugar y pasé ese parámetro a esa función para que arreglara el nombre de tipo.

Ésta es la función:

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 

Ésta es la pieza de código, donde estoy haciendo la llamada a la base de datos:

'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) 
+0

Agradable. esto funcionó. +1 –

Cuestiones relacionadas