2012-03-20 5 views
2

мне нужен таблица контура tab_A ввода ввода и обновление таблицы tab_B в соответствии с содержанием в каждой возвращаемой записи:Выберите и обновите; 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? –

+1

Как правило, в Sql вы хотите думать, как обновлять наборы записей, а не через них. – HLGEM

ответ

3

Вы можете включить регулярный оператор выбора в операторе обновления довольно легко заменить SELECT * с UPDATE table...

Это позволяет сначала проверить, что будут обновлены до фактического применения обновления.

Выбрать заявление

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 (Common Таблица Expression) Заказы ваши данные таким образом, что для каждого item рассчитывается RowNum (при этом последний получает RowNum = 1).

С помощью этого вы можете легко обновить свой tab_B в одном заявлении - не требуется цикл чередования по агонистической цепочке!

Смежные вопросы