详细信息
产品名称 | SQL Server |
事件编号 | 4186 |
事件源 | MSSQLSERVER |
组件 | SQLEngine |
符号名称 | |
消息正文 | 列 '%ls。%.*ls' 不能在 OUTPUT 子句中引用,因为列定义包含子查询或引用执行用户或系统数据访问的函数。 如果函数未绑定架构,则默认假定函数执行数据访问。 请考虑从列定义中删除子查询或函数,或者从 OUTPUT 子句中删除该列。 |
说明
为防止非确定性行为,当列由下列方法之一定义时,OUTPUT 子句无法从视图或内联表值函数引用列:
子查询。
执行用户或系统数据访问或假定执行此类访问的用户定义函数。
一个计算列,其中包含一个用户定义的函数,该函数在其定义中执行用户或系统数据访问。
例子
查看子查询定义的列
以下示例创建一个视图,该视图使用选择列表中的子查询来定义列 State
。 然后,UPDATE 语句将在 OUTPUT 子句中引用State
列,并由于选择列表中的子查询而失败。
USE AdventureWorks2012;
GO
CREATE VIEW dbo.V1
AS
SELECT City,
-- subquery to return the State name
(SELECT Name FROM Person.StateProvince AS sp
WHERE sp.StateProvinceID = a.StateProvinceID) AS State
FROM Person.Address AS a;
GO
--Reference the State column in the OUTPUT clause of an UPDATE statement
UPDATE dbo.V1
SET City = City + 'Test'
OUTPUT deleted.City, deleted.State, inserted.City, inserted.State
WHERE State = 'Texas';
GO
查看函数定义的列
以下示例创建一个视图,该视图使用选择列表中的数据访问标量函数 dbo.ufnGetStock
来定义列 CurrentInventory
。 然后,UPDATE 语句在 OUTPUT 子句中引用 CurrentInventory
列。
USE AdventureWorks2012;
GO
CREATE VIEW Production.ReorderLevels
AS
SELECT ProductID, ProductModelID, ReorderPoint,
dbo.ufnGetStock(ProductID) AS CurrentInventory
FROM Production.Product;
GO
UPDATE Production.ReorderLevels
SET ReorderPoint += CurrentInventory
OUTPUT deleted.ReorderPoint, deleted.CurrentInventory,
inserted.ReorderPoint, inserted.CurrentInventory
WHERE ProductModelID BETWEEN 75 and 80;
用户操作
可通过以下方法之一更正错误 4186:
使用联接而不是子查询来定义视图或函数中的列。 例如,可以按如下所示重写视图
dbo.V1
。USE AdventureWorks2012; GO CREATE VIEW dbo.V1 AS SELECT City, sp.Name AS State FROM Person.Address AS a JOIN Person.StateProvince AS sp ON sp.StateProvinceID = a.StateProvinceID;
检查用户定义函数的定义。 如果函数不执行用户或系统数据访问,请更改该函数以包含 WITH SCHEMABINDING 子句。
从 OUTPUT 子句中删除列。