MSSQLSERVER_4186

适用于:SQL Server

详细信息

属性
产品名称 SQL Server
事件 ID 4186
事件来源 MSSQLSERVER
组件 SQLEngine
符号名称
消息正文 无法在 OUTPUT 子句中引用列 '%ls.%.*ls',因为该列的定义中包含一个子查询或者引用一个执行用户或系统数据访问的函数。 默认情况下,如果函数未绑定到架构,则会认为该函数执行数据访问。 请考虑从列定义中删除子查询或函数,或者从 OUTPUT 子句中删除该列。

说明

为了防止出现不确定的行为,当某个列是通过下列方法之一定义时,OUTPUT 子句不能通过视图或内联表值函数引用该列:

  • 子查询。

  • 执行用户数据访问或系统数据访问或者被认为执行此种访问的用户定义函数。

  • 定义中包含执行用户数据访问或系统数据访问的用户定义函数的计算列。

示例

子查询定义的视图列

以下示例创建使用选择列表中的子查询定义 State 列的视图。 然后,UPDATE 语句在 OUTPUT 子句中引用 State 列,并且因为选择列表中的子查询而失败。

USE AdventureWorks2022;  
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 AdventureWorks2022;  
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 AdventureWorks2022;  
    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)