我正在进行大量CRUD操作,并在CUD之外创建合并存储过程。我存储的过程看起来像这样
CREATE PROCEDURE usp_AdministrationHistoryMerge
@AdministrationHistoryID int out,
@AdministratorID int,
@DateCreated datetime,
@CreatedBy nvarchar(50),
@ModifiedBy nvarchar(50),
@Action int
AS
SET NOCOUNT OFF
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
DECLARE @ERROR_SEVERITY int,
@MESSAGE varchar(1000),
@ERROR_NUMBER int,
@ERROR_PROCEDURE nvarchar(200),
@ERROR_LINE int,
@ERROR_MESSAGE nvarchar(4000),
@IsActive bit,
@DateModified datetime;
begin try
if @Action = 1
begin
set @IsActive = 1
set @AdministrationHistoryID = SCOPE_IDENTITY()
end
merge [AdministrationHistory] as target
using (select @AdministratorID, @DateCreated, @CreatedBy, @DateModified, @ModifiedBy, @IsActive)
as source (AdministratorID, DateCreated, CreatedBy, DateModified, ModifiedBy, IsActive)
on (target.AdministrationHistoryID = source.AdministrationHistoryID)
when matched and @Action = -1 then
update
set IsActive = 0
when matched and @Action = 0 then
update
set ModifiedBy = @ModifiedBy,
DateModified = GETDATE()
when matched and @Action = 1 then
insert
(AdministratorID, DateCreated, CreatedBy, IsActive)
values
(@AdministratorID, @DateCreated, @CreatedBy, @IsActive);
end try
BEGIN CATCH
SET @ERROR_SEVERITY = ISNULL(ERROR_SEVERITY(),'');
SET @ERROR_NUMBER = ISNULL(ERROR_NUMBER(),'');
SET @ERROR_PROCEDURE = ISNULL(ERROR_PROCEDURE(),'');
SET @ERROR_LINE = ISNULL(ERROR_LINE(),'');
SET @ERROR_MESSAGE = ISNULL(ERROR_MESSAGE(),'');
-- Test if the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
--PRINT N'The transaction is in an uncommittable state. Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
-- Test if the transaction is active and valid.
IF (XACT_STATE()) = 1
BEGIN
--PRINT N'The transaction is committable. Committing transaction.'
COMMIT TRANSACTION;
END;
SET @MESSAGE = 'Error Occured in Stored Procedure ' + cast(@ERROR_PROCEDURE as varchar(200)) +
'; Line Number ' + cast(@ERROR_LINE as varchar) +
'; Message: [' + cast(@ERROR_NUMBER as varchar) + '] - '
+ cast(@ERROR_MESSAGE as varchar(255))
RAISERROR(@MESSAGE, @ERROR_SEVERITY, 1);
END CATCH;
当我执行此操作时,我得到了这个完整的错误
消息10714,级别15,状态1,过程usp_AdministrationHistoryMerge,第36行在MERGE语句的“
UPDATE”子句中,“ WHEN MATCHED”类型的动作不能出现多次。
我四处寻找SO,并找到了解决此问题的几种方法,但是我发现的解决方案并不适合此错误,因为不是删除,而是需要将记录的IsActive更新为0。
另外,在我的搜索中,没有人能真正解释为什么会引发此错误,是的,我知道它很明显,因为错误就在那里,但是为什么不允许这种错误发生呢?在这种情况下,关于如何实现这一点有什么想法吗?还是应该在@Action为0时让此合并调用另一个storedproc?
在您的MERGE
陈述中,您有三个WHEN MATCHED
子句
UPDATE
声明INSERT
声明。但是,这是不允许的。在MERGE的文档中明确指出:
该
MERGE
语句最多可以包含两个WHEN MATCHED
子句。
和
如果有两个
WHEN MATCHED
子句,则一个子句必须指定一个UPDATE
动作,另一个子句必须指定一个DELETE
动作。
同样重要的是要知道:
如果
UPDATE
在子句中指定,并且 的多行与基于 的target_table中的一行匹配,则SQL
Server返回错误。该MERGE
语句不能多次更新同一行,也不能更新和删除同一行。
问题内容: 我必须在表target_table中插入/更新一些记录。这些记录是一个source_table。 我正在使用MERGE更新/插入target_table。 我想在更新中添加一些特定条件。 那么就应该只有更新,否则就没有更新或插入。 问题答案: 您可以简单地在中添加子句。在oracle docs中有更多关于它的信息。 因此,在您的情况下,它应如下所示:
问题内容: 假设我有这个SQL查询: 如果我尝试执行此操作,则会收到一条错误消息,提示“ ISNULL附近的语法不正确”。我知道这是ISNULL的正确语法。为什么不能在CONTAINS语句内部调用ISNULL? 问题答案: 试试这个: 当您尝试将表达式放入存储过程调用时,这是相同的问题: CONTAIN需要字符串文字,请参见CONTAINS(Transact-SQL)
问题内容: 我正在使用一条语句来添加新记录或更新当前记录。我有多个线程通过多个连接和多个语句(每个线程一个连接和一个语句)来驱动数据库。我一次要批处理50个语句。 我很惊讶在考试中遭到违反。我希望这是不可能的,因为将作为单个事务执行,或者是吗? 我的Java代码如下所示: 查询如下所示: 该错误显示为: 表格上的键是字段上的键。 问题答案: 是原子的,意味着所有更改都已提交或所有更改都已回滚。 在
问题内容: 我已经习惯了MSSQL,而不是Mysql,所以对这个可能很愚蠢的问题感到抱歉。我正在尝试通过运行以下查询来更新备份数据库的密码: 当我运行它时,它说 查询正常,受影响的0行(0.01秒)匹配的行:1已更改:0警告:0 为什么行匹配但没有变化? 问题答案: 这意味着该值未更改。由于该列已等于的md5哈希值,因此可能未更改。
问题内容: 为什么下面的代码: 给出错误: 在循环外继续 问题答案: 失败是switch语句的标准行为,因此,在switch语句中使用Continue没有意义。Continue语句仅在for / while / do..while循环中使用。 根据我对您意图的理解,您可能想写: 我还建议您将默认条件放在最后。 编辑:continue语句不能在switch语句中使用并不完全正确。(带有理想标记的)
问题内容: 以下Java代码无法编译。 为什么?在没有先声明的情况下,没有代码路径可导致程序将1分配给该路径。 我想到的范围可能仅限于第一条陈述,但后来我不明白为什么。如果我真的不想不必要地声明以提高性能怎么办?我不喜欢声明后不使用变量。 (您可能想争论一下,我不可以在第二条语句中简单地声明b ,在这种情况下,请想象一下它可能在其他地方处于循环中。) 问题答案: 为什么?如果没有先声明,没有代码路