2015-08-13 2 views
1

Я пытаюсь передать значения в таблицу многозначных параметров хранимой процедуры, как это:Игнорирование столбца идентификации при передаче значения параметра табличного

DataTable Entries = new DataTable(); 
Entries.Columns.Add("InfoID", typeof (int)); 
Entries.Columns.Add("InfoValue", typeof (string)); 
foreach(FormInfoValue entry in FormEntries) { 
    Entries.Rows.Add(entry.InfoID, entry.InfoValue); 
} 
DataSet res = ExecuteStoredProcedure("SaveData", new SqlParameter[] { 
    new SqlParameter() { 
     DbType = DbType.String, ParameterName = "@FormID", Value = FormID 
    }, 
    new SqlParameter() { 
     SqlDbType = SqlDbType.Structured, ParameterName = "@InfoValues", Value = Entries 
    }, 
    new SqlParameter() { 
     DbType = DbType.Int32, ParameterName = "@UserID", Value = Security.SessionControl.GetSession().UserID 
    } 
}); 
return int.Parse(res.Tables[0].Rows[0][0].ToString()); 

Но проблема в том, что табличное значении параметр @InfoValues имеет один дополнительный столбец, который является личным. Я использую этот столбец в своей логике в хранимой процедуре. Но на C# его исключение бросания состоит из 3 столбцов вместо 2 в @InfoValues. Как передать значения, игнорируя столбец идентификаторов в этом параметре таблицы?

UPDATE

Я пытался использовать временную таблицу в качестве решения, как это:

DECLARE @FormData TABLE (
    ID INT IDENTITY(1,1) NOT NULL, 
    InfoID INT NULL, 
    InfoValue NVARCHAR(MAX) NULL 
    ) 
INSERT INTO @FormData(InfoID,InfoValue) SELECT [InfoID],[InfoValue] FROM @InfoValues 
     WHILE (1 = 1) 
     BEGIN 
      EXEC [dbo].OpenKeys 
      SELECT TOP 1 @iid = [ID], @id = InfoID, @value = InfoValue FROM @FormData WHERE [ID] > @iid ORDER BY [ID] 
      -- Exit loop if no more info values 
      IF @@ROWCOUNT = 0 BREAK; 

      INSERT INTO [InfoValues]([InfoID],[Value],[UserID],[DateAdded],[DateUpdated]) 
      VALUES(@id,[dbo].ENCRYPTDATA(@value),@UserID,GETDATE(), GETDATE()); 
      SET @retID = SCOPE_IDENTITY(); 
      INSERT INTO EVMap(EntryID, ValueID) VALUES(@EntryID, @retID) 
     END 

такой подход эффективен?

+0

Почему бы не изменить вашу процедуру, чтобы использовать ROW_NUMBER вместо идентификатора? –

+0

@SeanLange Для этого я думаю, что мне нужно изменить много кода. Могу ли я использовать временную таблицу, которая содержит первичный ключ? Сначала вставьте данные во временную таблицу и затем используйте ее в обработке? –

+0

Это возможность. Трудно сказать, что является лучшим/простым способом, не зная, что делает ваша процедура. –

ответ

2

Я, конечно, не могу проверить это, но он, по крайней мере, анализирует. Вот пример того, как это может выглядеть, используя OUTPUT вместо цикла. Предположим, что некоторые из переменных уже определены, и вы принимаете @InfoValues в качестве параметра таблицы.

EXEC [dbo].OpenKeys 

INSERT INTO [InfoValues] 
(
    [InfoID] 
    , [Value] 
    , [UserID] 
    , [DateAdded] 
    , [DateUpdated] 
) 
OUTPUT @EntryID  -- I assume this is set somewhere else in your code 
    , INSERTED.RetID -- or whatever column is your identity in InfoValues 
INTO EVMap(EntryID, ValueID) 
SELECT InfoID 
    , [dbo].ENCRYPTDATA(InfoValue) 
    , @UserID -- I assume this is set somewhere else in your code 
    , GETDATE() 
    , GETDATE() 
FROM @InfoValues 
+0

Спасибо alot @SeanLange. Ты спасатель. :) –