MSSQLSERVER_4186
Détails
Nom du produit | SQL Server |
ID de l’événement | 4186 |
Source de l’événement | MSSQLSERVER |
Composant | SQLEngine |
Nom symbolique | |
Texte du message | La colonne '%ls.%.*ls' ne peut pas être référencée dans la clause OUTPUT parce que la définition de colonne contient une sous-requête ou référence une fonction qui offre un accès aux données utilisateur ou système. Une fonction est censée par défaut offrir un accès aux données si elle n'est pas liée au schéma. Pensez à supprimer la sous-requête ou la fonction de la définition de colonne ou à supprimer la colonne de la clause OUTPUT. |
Explication
Pour empêcher tout comportement non déterministe, la clause OUTPUT ne peut pas référencer une colonne d'une vue ou fonction table lorsque cette colonne est définie par l'une des méthodes suivantes :
Une sous-requête.
Une fonction définie par l'utilisateur qui offre un accès à des données utilisateur ou système, ou qui est supposée permettre d'y accéder.
Une colonne calculée qui contient une fonction définie par l’utilisateur qui effectue un accès aux données utilisateur ou système dans sa définition.
Exemples
Colonne de vue définie par une sous-requête
L'exemple suivant crée une vue qui utilise une sous-requête dans la liste de sélection pour définir la colonne State
. Une instruction UPDATE référence ensuite la colonne State
dans la clause OUTPUT et échoue en raison de la sous-requête dans la liste de sélection.
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
Colonne de vue définie par une fonction
L’exemple suivant crée une vue qui utilise la fonction scalaire d’accès aux données dbo.ufnGetStock
dans la liste de sélection pour définir la colonne CurrentInventory
. Une instruction UPDATE référence ensuite la colonne CurrentInventory
dans la clause 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;
Action de l'utilisateur
L'erreur 4186 peut être corrigée de l'une des façons suivantes :
Utilisez des jointures au lieu de sous-requêtes pour définir la colonne dans la vue ou fonction. Par exemple, vous pouvez réécrire la vue
dbo.V1
de la façon suivante.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;
Examinez la définition de la fonction définie par l'utilisateur. Si la fonction n'effectue pas accès aux données utilisateur ou système, modifiez la fonction de façon à y inclure la clause WITH SCHEMABINDING.
Supprimez la colonne de la clause OUTPUT.