我想使用内部联接对表进行一种“批量更新”。这是它的工作原理。在T-SQL中,如何确保只有在更新同一UPDATE语句中的所有其他列值后才更新列值?
有两个问题表,其中之一正在更新。我会打电话给正在更新的OriginalTable
和另一个UpdateData
。
OriginalTable
和UpdateData
都包含名为Id
的PK列,我们稍后再加入。 OriginalTable
包含许多其他列,所有这些列都是nvarchars,我会将这些列称为数据列。最后,OriginalTable
还包含一个校验和列,我希望在给定行的数据列中包含字符串连接数据的SHA1哈希值。 UpdateData
包含OriginalTable
中的数据列子集,这就是用来指定将OriginalTable
中的数据更新为的内容。
如果UpdateData
中的值是非空字符串或NULL,那么我想用该值更新OriginalTable
中的对应行。如果该值为空字符串,那么我不想修改OriginalTable
行的值。
比方说,在OriginalTable
的数据列有:FirstName
,LastName
,MI
,Age
。假设UpdateData
中的数据列是:FirstName
,LastName
,Age
。这基本上意味着我们正在更新除了MI
之外的所有信息。
我能完成这次更新这个SQL:
UPDATE T
SET FirstName = CASE UD.FirstName WHEN '' THEN T.FirstName ELSE UD.FirstName END,
LastName = CASE UD.LastName WHEN '' THEN T.LastName ELSE UD.LastName END,
Age = CASE UD.Age WHEN '' THEN T.Age ELSE UD.Age END
FROM #OriginalTable T
INNER JOIN #UpdateData UD
ON T.Id = UD.Id;
这点不错。现在,我面临的挑战是,当涉及到更新行的Checksum值时,我不知道如何保证散列计算只会在其他行被更新后才会发生。我应该提到,校验和计算必须在同一个语句中进行。我想要做这样的事情:
UPDATE T
SET FirstName = CASE UD.FirstName WHEN '' THEN T.FirstName ELSE UD.FirstName END,
LastName = CASE UD.LastName WHEN '' THEN T.LastName ELSE UD.LastName END,
Age = CASE UD.Age WHEN '' THEN T.Age ELSE UD.Age END,
Checksum = CONVERT(varchar(40), HASHBYTES('SHA1', T.FirstName + T.LastName + T.MI + T.Age), 2)
FROM #OriginalTable T
INNER JOIN #UpdateData UD
ON T.Id = UD.Id;
我需要在更新后计算OriginalTable
与值校验列的值。我怎样才能在同一个UPDATE语句中完成这个散列计算,保证在其他列更新后计算它的数据?
你就不能让它两种说法,但在交易中换呢?您是否有理由在单一声明中完成?这仅仅是为了原子性吗? – Charleh 2014-08-28 15:50:21
更新不是整个系列的事件。它发生在一次。如果你想这样做,你需要在你的HASHBYTES函数中添加所有的case表达式或者进行第二次更新。你有它编码你的HASHBYTES的方式将使用当前值,而不是新的价值将是什么。 – 2014-08-28 15:51:11
老实说,我会考虑让你的Checksum成为一个计算列。这将避免你必须与它搏斗。 – 2014-08-28 15:52:21