MSSQLSERVER_4186
Gilt für: SQL Server
Details
attribute | Wert |
---|---|
Produktname | SQL Server |
Ereignis-ID | 4186 |
Ereignisquelle | MSSQLSERVER |
Komponente | SQLEngine |
Symbolischer Name | |
Meldungstext | Auf die Spalte "%ls.%.*ls" kann in der OUTPUT-Klausel nicht verwiesen werden, weil die Spaltendefinition eine Unterabfrage enthält oder auf eine Funktion verweist, die einen Zugriff auf Benutzer- oder Systemdaten ausführt. Für eine Funktion, die nicht schemagebunden ist, wird standardmäßig angenommen, dass sie auf Daten zugreift. Erwägen Sie, die Unterabfrage bzw. die Funktion aus der Spaltendefinition zu entfernen oder die Spalte aus der OUTPUT-Klausel zu entfernen. |
Erklärung
Um nicht deterministisches Verhalten zu vermeiden, darf die OUTPUT-Klausel nicht auf eine Spalte einer Sicht oder Inline-Tabellenwertfunktion verweisen, wenn diese Spalte mithilfe einer der folgenden Methoden definiert wurde:
Eine Unterabfrage.
Eine benutzerdefinierte Funktion, die auf Benutzer- oder Systemdaten zugreift bzw. bei der davon ausgegangen wird, dass sie einen solchen Zugriff ausführt.
Eine berechnete Spalte, die eine benutzerdefinierte Funktion enthält, die in ihrer Definition auf Benutzer- oder Systemdaten zugreift.
Beispiele
Von einer Unterabfrage definierte Sichtspalte
Im folgenden Beispiel wird eine Sicht erstellt, die eine Unterabfrage in der Auswahlliste verwendet, um die Spalte State
zu definieren. Anschließend verweist eine UPDATE-Anweisung auf die State
-Spalte in der OUTPUT-Klausel und verursacht aufgrund der Unterabfrage in der Auswahlliste einen Fehler.
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
Von einer Funktion definierte Sichtspalte
Im folgenden Beispiel wird eine Sicht erstellt, die eine Datenzugriff-Skalarfunktion dbo.ufnGetStock
in der Auswahlliste verwendet, um die CurrentInventory
-Spalte zu definieren. Anschließend verweist eine UPDATE-Anweisung auf die CurrentInventory
-Spalte in der OUTPUT-Klausel.
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;
Benutzeraktion
Sie können Fehler 4186 auf eine der folgenden Arten beheben:
Verwenden Sie anstelle von Unterabfragen Joins, um die Spalte in der Sicht oder der Funktion zu definieren. Sie können die Sicht
dbo.V1
z. B. wie folgt umschreiben.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;
Untersuchen Sie die Definition der benutzerdefinierten Funktion. Wenn die Funktion keinen Zugriff auf Benutzer- oder Systemdaten ausführt, können Sie die Funktion ändern, um die WITH SCHEMABINDING-Klausel einzubinden.
Entfernen Sie die Spalte aus der OUTPUT-Klausel.