简体   繁体   中英

Ignoring identity column when passing value to a table-valued parameter

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM