我正在处理这个需要先插入行然后更新行的存储过程。我遇到的问题是抓取最初插入的行的id,以便稍后我可以更新正确的行。
目前,这需要我的Visual Studio程序在我的程序中定义@searchID。但是,我只想让行id对存储过程“本地”,而不是在Visual Studio中与我的程序进行交互。有没有办法在存储过程中创建一个局部变量,或许在Visual Studio中没有触及我的c#代码?
LF-CR
答案 0 :(得分:4)
首先,除非您进行初始设置更改,否则NULL
运算符使用=
无法检查IS
。所以它应该是
IF @searchID IS null
要获取最后插入的标识值,请在动态查询中添加set @searchID = SCOPE_IDENTITY()
并通过输出参数获取结果。
set @Query = 'INSERT into Registrant(DateCreated,EventId,FormId,'+
(@ColumnName) +') values (CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue)
set @searchID = SCOPE_IDENTITY()'
set @ParmDefinition = N'@ColumnValue varchar(100), @EventID int, @FormID int,@searchID INT OUTPUT'
exec sp_executesql @Query, @ParmDefinition,
@ColumnValue = @ColumnValue,
@EventID = @EventID,
@FormID = @FormID,
@searchID = @searchID OUTPUT;
更新查询
set @Query2 = 'UPDATE Registrant SET DateCreated = CURRENT_TIMESTAMP, EventId = @EventId, FormId = @FormId, ' +quotename(@ColumnName)+ ' = @ColumnValue WHERE RegistrantId = @searchID'
set @ParmDefinition2 = N'@ColumnValue varchar(100), @EventID int, @FormID int, @searchID int'
exec sp_executesql @Query2, @ParmDefinition2,
@ColumnValue = @ColumnValue,
@EventID = @EventID,
@FormID = @FormID,
@searchID = @searchID
答案 1 :(得分:1)
将INSERT
和UPDATE
作为单独查询的替代方法是使用MERGE。查询应类似于下面的查询(将其视为伪代码):
MERGE Registrant AS target
USING (
SELECT CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue
)
ON (RegistrantId = @searchID)
WHEN MATCHED THEN
UPDATE SET EventId = @EventId, FormId = @FormId ...
WHEN NOT MATCHED THEN
INSERT into Registrant(DateCreated,EventId,FormId,'+
(@ColumnName) +') values (CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue)
(DateCreated,EventId,FormId, @ColumnName)
VALUES (CURRENT_TIMESTAMP, @EventId, @FormId, @ColumnValue)
MERGE具有以原子方式执行(一切都成功或失败)的优势,您还可以将其用于批处理操作(一次查找多个搜索标识符INSERT
或UPDATE
)