Condividi tramite


MSSQLSERVER_4186

Dettagli

Nome prodotto SQL Server
ID evento 4186
Origine dell'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 accede a dati utente o di 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 evitare un comportamento non deterministico, la clausola OUTPUT non può fare riferimento a una colonna da una vista o da una funzione con valori di tabella inline quando tale colonna è definita da uno dei metodi seguenti:

  • Sottoquery.

  • Funzione definita dall'utente che esegue l'accesso ai dati utente o di sistema oppure si presuppone che esegua tale accesso.

  • Colonna calcolata che contiene una funzione definita dall'utente che esegue l'accesso ai dati utente o di sistema nella relativa definizione.

Esempi

Visualizzare la colonna definita da una sottoquery

Nell'esempio seguente viene creata una vista che usa una sottoquery nell'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 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  

Visualizzare la colonna definita da una funzione

Nell'esempio seguente viene creata una vista che utilizza la funzione scalare dbo.ufnGetStock per l'accesso ai dati nella lista di selezione per definire la colonna CurrentInventory. Un'istruzione UPDATE fa quindi riferimento alla CurrentInventory colonna nella clausola 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;  

Azione utente

L'errore 4186 può essere corretto 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 indicato di seguito.

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

  • Rimuovere la colonna dalla clausola OUTPUT.

Vedere anche

Clausola OUTPUT (Transact-SQL)