MSSQLSERVER_4186

 

Veröffentlicht: Mai 2016

ProduktnameSQL Server
Ereignis-ID4186
EreignisquelleMSSQLSERVER
KomponenteSQLEngine
Symbolischer Name
MeldungstextAuf die Spalte "%ls. %.*ls" kann nicht in der OUTPUT-Klausel verwiesen werden, da die Spaltendefinition eine Unterabfrage enthält oder auf eine Funktion verweist, die den Benutzer- oder Systemdatenzugriff 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.

Um nicht deterministisches Verhalten zu vermeiden, kann 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 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

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 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;

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 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;
    
    
  • 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.

OUTPUT-Klausel (Transact-SQL)

Anzeigen: