MSSQLSERVER_4186

Dettagli

Nome prodotto

SQL Server

Versione prodotto

10.50

Numero di build del prodotto

 

ID evento

4186

Origine evento

MSSQLSERVER

Componente

SQLEngine

Nome simbolico

 

Testo del messaggio

Colonna '%ls.%. Impossibile fare riferimento a *ls' nella clausola OUTPUT perché la definizione di colonna contiene una sottoquery o fa riferimento a una funzione che esegue l'accesso ai dati dell'utente o del sistema. Si presuppone che le funzioni non associate a schema eseguano per impostazione predefinita l'accesso ai dati. Rimuovere la sottoquery o la funzione dalla definizione di colonna o rimuovere la colonna dalla clausola OUTPUT.

Spiegazione

Per impedire il comportamento non deterministico, la clausola OUTPUT non può fare riferimento a una colonna di una vista o di una funzione in linea valutata a livello di tabella se la colonna in questione viene definita mediante uno dei metodi seguenti:

  • Sottoquery.

  • Funzione definita dall'utente che esegue, o si presume esegua, l'accesso ai dati dell'utente o di sistema.

  • Una colonna calcolata che contiene una funzione definita dall'utente che esegue l'accesso ai dati dell'utente o del sistema nella relativa definizione.

Esempi

Visualizzazione di una colonna definita da una sottoquery

Nell'esempio seguente viene creata una vista che utilizza una sottoquery dell'elenco di selezione per definire la colonna State. Un'istruzione UPDATE fa quindi riferimento alla colonna State nella clausola OUTPUT e ha esito negativo a causa della sottoquery nell'elenco di selezione.

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

Visualizzazione di una colonna definita da una funzione

Nell'esempio seguente viene creata una vista che utilizza la funzione scalare di accesso ai dati dbo.ufnGetStock dell'elenco di selezione per definire la colonna CurrentInventory. Un'istruzione UPDATE fa quindi riferimento alla colonna CurrentInventory nella clausola OUTPUT.

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

Azione utente

È possibile correggere l'errore 4186 in uno dei modi seguenti:

  • Utilizzare i join anziché le sottoquery per definire la colonna nella vista o nella funzione. È ad esempio possibile riscrivere la vista dbo.V1 come segue.

    USE AdventureWorks2008R2;
    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;
    
  • Esaminare la definizione della funzione definita dall'utente. Se la funzione non esegue l'accesso ai dati dell'utente o del sistema, modificarla in modo da includere la clausola WITH SCHEMABINDING.

  • Rimuovere la colonna dalla clausola OUTPUT.

Vedere anche

Riferimento