Поделиться через


MSSQLSERVER_4186

Сведения

Название продукта SQL Server
Идентификатор события 4186
Источник события MSSQLSERVER
Компонент SQLEngine
Символическое имя
Текст сообщения Нельзя ссылаться на столбец «%ls.%.*ls» из предложения OUTPUT, так как определение столбца содержит вложенный запрос или ссылку на функцию, которая выполняет доступ к системным данным или данным пользователя. По умолчанию предполагается, что функция выполняет доступ к данным, если она не привязана к схеме. Рассмотрите возможность удаления вложенного запроса или функции из определения столбца либо удаления столбца из предложения OUTPUT.

Объяснение

Чтобы предотвратить недетерминированное поведение, предложение OUTPUT не может ссылаться на столбец из представления или встроенной табличной функции, если этот столбец определен одним из следующих методов:

  • Вложенный запрос.

  • Определяемая пользователем функция, которая выполняет доступ к данным пользователя или системы, или предполагается, что выполняет такой доступ.

  • Вычисляемый столбец, содержащий определяемую пользователем функцию, которая в своём определении выполняет доступ к пользовательским или системным данным.

Примеры

Просмотр столбца, определенного вложенным запросом

В следующем примере создается представление, использующее вложенный запрос в списке выбора для определения столбца State. Затем инструкция UPDATE ссылается на State столбец в предложении OUTPUT и завершается ошибкой из-за вложенного запроса в списке выбора.

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 обращается к столбцу CurrentInventory в разделе OUTPUT.

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)