将值传递给 table 值参数时忽略标识列
Ignoring identity column when passing value to a table-valued parameter
我正在尝试将值传递给存储过程的 table 值参数,如下所示:
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());
但问题是 Table 值参数 @InfoValues
有一个额外的列,即标识。我在存储过程的逻辑中使用该列。但在 C# 中,它抛出的异常是 @InfoValues
中有 3 列而不是 2 列。如何通过忽略此 table 值参数中的标识列来传递值?
更新
我尝试使用临时 table 作为这样的解决方案:
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
这种方法有效吗?
我当然不能测试这个,但它至少可以解析。这是使用 OUTPUT
而不是循环的示例。这假设一些变量已经定义并且您收到 @InfoValues
作为 table 值参数。
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
我正在尝试将值传递给存储过程的 table 值参数,如下所示:
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());
但问题是 Table 值参数 @InfoValues
有一个额外的列,即标识。我在存储过程的逻辑中使用该列。但在 C# 中,它抛出的异常是 @InfoValues
中有 3 列而不是 2 列。如何通过忽略此 table 值参数中的标识列来传递值?
更新
我尝试使用临时 table 作为这样的解决方案:
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
这种方法有效吗?
我当然不能测试这个,但它至少可以解析。这是使用 OUTPUT
而不是循环的示例。这假设一些变量已经定义并且您收到 @InfoValues
作为 table 值参数。
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