2012-03-29 115 views
7

我傳遞一個DataTable從代碼到存儲過程在這樣表變量。無法訪問存儲過程

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. 

無法解決該錯誤。

+0

這可能有助於http://msdn.microsoft。 com/en-us/library/bb510489(SQL.100).aspx – 2012-03-29 07:49:45

回答

15

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

不錯。這工作。 +1 – 2013-11-09 09:45:53

+0

不錯,非常好。 – user960567 2014-05-06 11:27:01

+0

非常棒..你節省了更多時間..謝謝.. :-) – 2015-03-27 10:50:03

1

如果你只有一個或兩個表的參數,你不通過所有的參數都循環。我寫了一個函數,並將該參數傳遞給該函數,以便修復該類型名稱。

這是函數:

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

不錯。這工作。 +1 – 2013-11-09 09:45:05