2012-03-20 93 views
2

我需要循环表的录入和更新表tab_Btab_A条目根据每个返回的条目内容:选择并更新; SQL Server的

SELECT item, regBy, MAX(regTime) AS latestUpdateTime 
FROM tab_A 
GROUP BY item, regBy; 

其结果必然是循环的入口进入,并且必须为每个条目执行以下UPDATE :

UPDATE tab_B 
SET lastUpdated = "data from latestUpdateTime in SQL above" 
lastUpdBy = "data from regBy in SQL above" 
WHERE item = "data from item in SQL above" 

我不熟悉Transact SQL,所以任何帮助,将不胜感激。

+3

你可以发布**表结构吗?**列名,它们的数据类型,可能的约束等。另外:你正在使用SQL Server的哪个版本? 7.0? 2000? 2005年? 2008年? 2008 R2 ?? – 2012-03-20 13:47:34

+1

一般在Sql中,您想要考虑如何更新记录集,而不是循环遍历它们。 – HLGEM 2012-03-20 13:54:35

回答

3

您可以通过UPDATE table...

这使您可以先验证会有什么实际应用更新之前得到更新替换SELECT *把一个普通的SELECT语句为update语句很容易。

Select语句

SELECT * 
FROM tab_B b 
     INNER JOIN (
      SELECT item 
        , regBy 
        , MAX(regTime) AS latestUpdateTime 
     FROM  tab_A 
     GROUP BY 
        item 
        , regBy 
     ) a ON a.item = b.item 

Update语句

UPDATE tab_B 
SET lastUpdated = a.latestUpdateTime 
     , lastUpdBy = a.regBy 
FROM tab_B b 
     INNER JOIN (
      SELECT item 
        , regBy 
        , MAX(regTime) AS latestUpdateTime 
     FROM  tab_A 
     GROUP BY 
        item 
        , regBy 
     ) a ON a.item = b.item 

另一种方法来验证更新,并根据您的版本将是启动事务并使用OUTPUT条款。

BEGIN TRAN 

UPDATE tab_B 
SET lastUpdated = a.latestUpdateTime 
     , lastUpdBy = a.regBy 
OUTPUT INSERTED.* 
FROM tab_B b 
     INNER JOIN (
      SELECT item 
        , regBy 
        , MAX(regTime) AS latestUpdateTime 
     FROM  tab_A 
     GROUP BY 
        item 
        , regBy 
     ) a ON a.item = b.item 

ROLLBACK TRAN   
2

如果你使用SQL Server 2005 或更新,你可以做这样的事情:

;WITH TableAData AS 
(
    SELECT 
     item, regBy, regTime, 
     RowNum = ROW_NUMBER() OVER(PARTITION BY item ORDER BY regTime DESC) 
    FROM dbo.tab_A 
) 
UPDATE dbo.tab_B 
SET 
    lastUpdated = a.regTime, 
    lastUpdBy = a.regby 
FROM TableAData a  
WHERE 
    tab_B.item = a.item 
    AND a.RowNum = 1 

基本上,这CTE(公共表表达式)的订单以这样的方式您的数据对于每个item,计算出RowNum(最近的一个得到RowNum = 1)。

有了这个,您可以轻松地在一个语句中更新您的tab_B - 不需要逐行拼凑行循环!