MSSQLSERVER_4186

详细信息

产品名称 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 子句中删除列。

另请参阅

OUTPUT 子句(Transact-SQL)