2012-03-29 18 views
7

Przekazuję dane z kodu do procedury składowanej w ten sposób.Nie można uzyskać dostępu do zmiennej tabeli w procedurze przechowywanej

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

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

Próbuję uzyskać dostęp do tego parametru w przechowywanym proc.

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 

Ale kiedy wywołanie jest wykonywane do procedury przechowywanej, generuje błąd.

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. 

Nie można rozwiązać problemu.

+0

To może pomóc http://msdn.microsoft. com/en-us/library/bb510489 (SQL.100) .aspx –

Odpowiedz

15

Z powodu błędu w sposobie SqlCommandBuilder.DeriveParameters właściwość TypeName obiektu SqlParameter dla parametru tabeli wycenione zawiera nazwę bazy danych (patrz http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommandbuilder.deriveparameters.aspx, komentarz „Parametry Tabela ceniony nie wpisany poprawnie”).

Rozwiązaniem tego można dodać ten kod ogólnego przeznaczenia tuż po utworzeniu komendy:

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

Nice. to działało. +1 –

+0

Fajnie, bardzo ładnie. – user960567

+0

Znakomity .. Zaoszczędziłeś więcej czasu .. Dzięki .. :-) –

1

Jeśli masz tylko jeden lub dwa parametry stole, nie ma pętli wszystkich parametrów. Zamiast tego napisałem funkcję i przekazałem ten parametr do tej funkcji, aby naprawić typename.

Jest to funkcja:

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 

To jest kawałek kodu, w którym robię połączenia do bazy danych:

'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

Nice. to działało. +1 –

Powiązane problemy