Stu*_*ner 4 sql-server sql-server-2012
给定以下针对 AdventureWorks 数据库的 SQL 代码:
begin transaction;
drop trigger Sales.iduSalesOrderDetail;
alter table Sales.SalesOrderDetail
add LineNumber int null;
go
with sod as (
select
SalesOrderID,
/* other cols */
LineNumber,
NewLineNumber = row_number() over
(partition by SalesOrderID order by SalesOrderDetailID) + 1
from Sales.SalesOrderDetail
where SalesOrderID <= 44000)
update sod
set LineNumber = NewLineNumber,
ModifiedDate = getdate()
output
inserted.SalesOrderID,
/* other cols */
inserted.LineNumber;
select
SalesOrderID,
/* other cols */
LineNumber
from Sales.SalesOrderDetail
where SalesOrderID <= 44000;
rollback transaction;
Run Code Online (Sandbox Code Playgroud)
在 SQL Server 2008R2 上运行此代码时,它运行良好;也就是说,它更新输入的数据Sales.SalesOrderDetail并输出结果,该结果与来自以下 SELECT 语句的数据相匹配。
但是,在 SQL Server 2012 上运行此代码时,我收到消息:
消息 4196,级别 16,状态 1,第 2 行
无法在 OUTPUT 子句中引用列“deleted.NewLineNumber”,因为列定义包含使用窗口函数的表达式。
这很奇怪,因为我没有以任何方式引用 delete.NewLineNumber。我尝试删除各种 OUTPUT 列并获得相同的结果。我发现停止错误的唯一两种方法是
row_number()(也就是说:) 的结果NewLineNumber = row_number() over (...);或者这可能是 SQL Server 如何处理 CTE 中的表达式的错误吗?有没有其他人遇到过这个问题?
我正在研究可能的解决方法,但我对此很好奇。
这是 SQL Server 2012 中的错误,将在 SP2 中修复:
解决方法是+ 1从ROW_NUMBER()计算中删除;这个虚假的错误信息消失了。重写这部分:
NewLineNumber = row_number() over
(partition by SalesOrderID order by SalesOrderDetailID)
---------------- remove the +1 here --------------------^^^
from Sales.SalesOrderDetail
where SalesOrderID <= 44000)
update sod
set LineNumber = NewLineNumber + 1,
------- and put it here -------^^^
Run Code Online (Sandbox Code Playgroud)