我正在执行以下意图:
我的查询中有一个有效合格的凭证代码列表/表格。 我想将此列表中的所有学生优惠券标记为已删除 = 0,并且如果它们出现在列表中,则将 is_applied 标记为 true。
对于student_header 表的给定外键student_header_id 下未出现的所有其他student_vouchers,我想将它们标记为已应用的 false 已删除。
以下代码执行得足够好,但是我似乎在与 Student_vouchers 交互的其他事务方面遇到了大量死锁。所以我认为如果我可以将其合并到单个更新操作中会更好,这可能吗?这样的改变是否有助于解决僵局?
DECLARE @applied_voucher_table table
(
value nvarchar(max)
);
-- REMOVE INVALID STUDENT VOUCHERS
UPDATE student_vouchers
SET is_applied = 0,
deleted = 1,
deleted_date = GETDATE(),
edited_date = GETDATE()
OUTPUT INSERTED.voucher_code INTO @DeletedVouchers
WHERE student_header_id = @HEADERID AND deleted = 0;
DECLARE @AppliedVouchers TABLE (voucher_code NVARCHAR(MAX));
IF (
(
SELECT COUNT(*)
FROM @applied_voucher_table
WHERE value IS NOT NULL
AND value != '') > 0
)
BEGIN
--UPDATE VALID VOUCHERS
UPDATE student_vouchers
SET is_applied = 1,
deleted = 0,
edited_date = GETDATE(),
OUTPUT INSERTED.voucher_code INTO @AppliedVouchers
WHERE student_header_id = @HEADERID
AND voucher_code IN
(SELECT value
FROM @applied_voucher_table
WHERE value IS NOT NULL AND value != '')
AND id IN (SELECT id
FROM @applied_voucher_table);
END;
student_vouchers (
id,
student_header_id,
voucher_code,
is_applied,
deleted,
deleted_date,
edited_date
如果有不清楚的地方请告诉我! 请注意,我收到此列表 @DeletedVouchers 很重要,但是最好也有 @AppliedVouchers 列表,它们都发送到远程进程。
您可以使用左连接和一些
CASE
或 IIF
表达式将两个表和更新合并为一个表。
DECLARE @UpdatedVouchers TABLE (voucher_code NVARCHAR(MAX) NOT NULL, is_deleted bit NOT NULL);
UPDATE sv
SET is_applied = IIF(avt.id IS NOT NULL, CAST(1 AS bit), CAST(0 AS bit)),
deleted = IIF(avt.id IS NOT NULL, CAST(0 AS bit), CAST(1 AS bit)),
deleted_date = IIF(avt.id IS NOT NULL, sv.deleted_date, GETDATE())
edited_date = GETDATE()
OUTPUT inserted.deleted, inserted.voucher_code
INTO @UpdatedVouchers (voucher_code, is_deleted)
FROM student_vouchers sv
LEFT JOIN @applied_voucher_table av
ON avt.value = sv.voucher_code
AND avt.value != ''
AND avt.id = sv.id
WHERE sv.student_header_id = @HEADERID
AND (sv.deleted = 0 OR avt.id IS NOT NULL);
请注意,左连接中的语义与原始语义略有不同,但我怀疑无论如何这是更正确的。在原始版本中,
id
和value
可以从不同的行进行匹配,看起来应该是一个带有两个内部EXISTS
条件的WHERE
。在此版本中,它们需要来自一行。