更新:我正在使用 Sql Server 2008 R2。
我将更新大量行,为了避免不必要的锁定,我将在每次更新大约一千行的匹配中执行此操作。
使用 SETROWCOUND我可以将更新限制为 1000 行,使用WHERE ID > x我可以设置它应该运行哪个批次。
但为了使其工作,我需要知道刚刚处理的批次中的最高 ID。
我可以让用户OUTPUT返回所有受影响的 ID 并找到代码中最高的 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)
Run Code Online (Sandbox Code Playgroud)
但这给了我这个错误
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
Run Code Online (Sandbox Code Playgroud)
有没有任何解决方法,任何人都可以解释为什么我可以将结果插入表中而不只是返回结果?
不要为此使用 SET ROWCOUNT (或者根本不要使用 SET ROWCOUNT),正如 BOL 所说:
使用 SET ROWCOUNT 不会影响 SQL Server 下一版本中的 DELETE、INSERT 和 UPDATE 语句!
不要在新的开发工作中将 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
Run Code Online (Sandbox Code Playgroud)