在T-SQL中,如果只更新了同一UPDATE语句中的所有其他列值后,如何保证列值更新?

时间:2014-08-28 15:45:51

标签: sql sql-server tsql join

我想做一些"批量更新"使用内部联接的表的这是它的工作原理。

有两个表有问题,其中一个表正在更新。我将调用正在更新的OriginalTable和另一个UpdateData

OriginalTableUpdateData都包含一个名为Id的PK列,我们稍后会加入该列。 OriginalTable包含许多其他列,所有列都是nvarchars,我将这些列称为数据列。最后,OriginalTable还包含 Checksum 列,我希望在给定行的数据列中包含字符串连接数据的SHA1哈希值。 UpdateData包含OriginalTable中数据列的子集,以及用于指定更新OriginalTable中数据的内容的内容。

如果UpdateData中的值是非空字符串或NULL,那么我想用OriginalTable更新该值的相应行。如果值为空字符串,则我不想修改OriginalTable行的值。

我们假设OriginalTable中的数据列为:FirstNameLastNameMIAge。我们假设UpdateData中的数据列为:FirstNameLastNameAge。这基本上意味着我们要更新除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;

这很好。现在,我面临的挑战是,当更新一行的校验和值时,我不知道如何保证只有在首先更新其他行之后才会进行哈希计算。我应该提一下,校验和计算在同一个语句中发生是至关重要的。我想做这样的事情:

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中的值计算Checksum列的值。如何在同一个UPDATE语句中完成此哈希计算,保证在其他列更新后计算数据?

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情(未经测试):

UPDATE T
SET FirstName = UD.FirstName,
    LastName = UD.LastName,
    Age = UD.Age,
    Checksum = CONVERT(varchar(40), HASHBYTES('SHA1', UD.FirstName + UD.LastName + T.MI + UD.Age), 2)
FROM #OriginalTable T 
INNER JOIN (
   SELECT T1.Id,
          CASE UD1.FirstName WHEN '' THEN T1.FirstName ELSE UD1.FirstName END AS FirstName,
          CASE UD1.LastName WHEN '' THEN T1.LastName ELSE UD1.LastName END AS LastName,
          CASE UD1.Age WHEN '' THEN T1.Age ELSE UD1.Age END AS Age
      FROM #OriginalTable T1
         INNER JOIN #UpdateData UD1 ON T1.Id = UD1.Id) AS UD
  ON T.Id = UD.Id;