2013-05-17 188 views
4

更新:我正在使用Sql Server 2008 R2。获取多行更新的最高ID

我要更新大量的行并避免不必要的锁定我将在每次更新大约1000行的匹配中执行此操作。

使用SET ROWCOUND我可以限制更新到1000行,并使用WHERE ID > x我可以设置它应该运行的批次。

但是为了这个工作,我需要知道刚刚处理的批次中的最高ID。

我可以让用户OUTPUT返回所有受影响的ID并找到代码中最高的一个,但我希望能够返回最高的ID。

我想这

SELECT MAX(id) 
FROM (
    UPDATE mytable 
    SET maxvalue = (SELECT MAX(salesvalue) FROM sales WHERE cid = t.id GROUP BY cid) 
    OUTPUT inserted.id 
    FROM mytable t 
    WHERE au.userid > 0 
) updates(id) 

但它给我这个错误 A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT statement that is not the immediate source of rows for an INSERT statement.

,但如果我尝试的结果插入表直接被有效

CREATE TABLE #temp(id int) 

INSERT INTO #temp 
SELECT MAX(id) 
FROM (
    UPDATE mytable 
    SET maxvalue = (SELECT MAX(salesvalue) FROM sales WHERE cid = t.id GROUP BY cid) 
    OUTPUT inserted.id 
    FROM mytable t 
    WHERE au.userid > 0 
) updates(id) 

drop table #temp 

有对此的任何解决方法,任何人都可以解释为什么我可以将结果插入到表中,但不只是返回结果?

回答

3

不要使用SET ROWCOUNT这个(或全部),如BOL说:

使用SET ROWCOUNT将不会影响DELETE,INSERT和 UPDATE语句在SQL Server的下一个版本!

不要使用SET ROWCOUNT DELETE,INSERT和UPDATE语句在新开发中 工作,并计划修改当前正在使用它的应用程序。另外,对于当前使用SET ROWCOUNT, 的DELETE,INSERT和UPDATE语句的 ,我们建议您重写它们以使用TOP语法。

你可以用表变量做到这一点,太:

DECLARE @Log TABLE (id INT NOT NULL); 

UPDATE TOP 1000 mytable 
SET maxvalue = (SELECT MAX(salesvalue) FROM sales WHERE cid = t.id GROUP BY cid) 
OUTPUT inserted.id INTO @Log 
FROM mytable t 
WHERE au.userid > 0 

SELECT maxid = MAX(id) 
FROM @Log 
+0

的Sql Server 2008 R2中似乎不喜欢TOP与更新,它会产生不正确的语法。 –

+0

但解决方案工作:) –