I am trying to pass values to a table-valued parameter of a stored procedure like this:
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());
But the problem is that the Table-valued parameter @InfoValues
has one extra column that is identity. I am using that column in my logic in stored procedure. But at C# its throwing exception of having 3 columns instead of 2 in @InfoValues
. How can I pass values by ignoring identity column in this table-valued parameter?
UPDATE
I tried to use a temp table as a solution like this:
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
Is this approach efficient?
I of course can't test this but it at least parses. Here is an example of how this might look using OUTPUT
instead of looping. This assume that some of the variable are already defined and you receive @InfoValues
as a table valued parameter.
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