MSSQLSERVER_4186

详细信息

产品名称

SQL Server

产品版本

10.0

产品内部版本号

 

事件 ID

4186

事件源

MSSQLSERVER

组件

SQLEngine

符号名称

 

消息正文

OUTPUT 子句中不允许使用列 '%ls.%.*ls',因为列定义包含一个子查询,或者引用执行用户数据访问或系统数据访问的函数。默认情况下,如果函数未绑定到架构,则会认为该函数执行数据访问。请考虑从列定义中删除子查询或函数,或者从 OUTPUT 子句中删除该列。

解释

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

  • 子查询。

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

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

示例

子查询定义的视图列

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

USE AdventureWorks;
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 AdventureWorks;
GO
CREATE VIEW Production.ReorderLevels
AS
    SELECT ProductID, ProductModelID, ReorderPoint,
           dbo.ufnGetStock(ProductID) AS CurrentInventory
    FROM Production.Product;

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 AdventureWorks;
    GO
    CREATE VIEW dbo.V1
    AS
        SELECT City, State
        FROM Person.Address AS a 
        JOIN Person.StateProvince AS sp 
        ON sp.StateProvinceID = a.StateProvinceID;
    
  • 检查用户定义函数的定义。如果函数未执行用户数据访问或系统数据访问,请更改此函数,使其包含 WITH SCHEMABINDING 子句。

  • 从 OUTPUT 子句中删除列。

请参阅

参考