Condividi tramite


Risoluzione dei problemi relativi alle dipendenze SQL

In questo argomento vengono descritti i problemi comuni relativi alle dipendenze tra gli oggetti e le relative soluzioni.

La funzione a gestione dinamica sys.dm_sql_referenced_entities non restituisce le dipendenze a livello di colonna

La funzione di sistema sys.dm_sql_referenced_entities restituirà tutte le dipendenze a livello di colonna per i riferimenti associati a schema. La funzione restituirà ad esempio tutte le dipendenze a livello di colonna per una vista indicizzata poiché una vista indicizzata richiede l'associazione allo schema. Tuttavia, quando l'entità a cui si fa riferimento non è associata a schema, le dipendenze della colonna vengono restituite solo quando è possibile associare tutte le istruzioni in cui si fa riferimento alle colonne. Le istruzioni possono essere associate correttamente solo se tutti gli oggetti esistono al momento dell'analisi delle istruzioni. Se un'istruzione definita nell'entità non viene associata, le dipendenze a livello di colonna non verranno restituite e la colonna referenced_minor_id restituirà 0. Quando le dipendenze della colonna non possono essere risolte, viene generato l'errore 2020. Questo errore non impedisce alla query di restituire le dipendenze a livello di oggetto.

Soluzione

Correggere gli errori identificati nel messaggio prima dell'errore 2020. Nell'esempio di codice seguente viene definita la vista Production.ApprovedDocuments nelle colonne Title, ChangeNumber e Status della tabella Production.Document. Viene eseguita una query sulla funzione di sistema sys.dm_sql_referenced_entities per gli oggetti e le colonne da cui dipende la vista ApprovedDocuments. Poiché la vista non viene creata utilizzando la clausola WITH SCHEMA_BINDING, è possibile modificare le colonne con riferimenti nella vista della tabella a cui si fa riferimento. Nell'esempio viene modificata la colonna ChangeNumber della tabella Production.Document rinominandola con TrackingNumber. Viene eseguita di nuovo una query sulla vista del catalogo per la vista ApprovedDocuments. Non è però possibile eseguire l'associazione a tutte le colonne definite nella vista. Vengono restituiti gli errori 207 e 2020 identificando il problema. Per risolvere il problema, è necessario modificare la vista in modo da riflettere il nuovo nome della colonna.

USE AdventureWorks2008R2;
GO
CREATE VIEW Production.ApprovedDocuments
AS
    SELECT Title, ChangeNumber, Status
    FROM Production.Document
    WHERE Status = 2;
GO
SELECT referenced_schema_name AS schema_name
    ,referenced_entity_name AS table_name
    ,referenced_minor_name AS referenced_column
FROM sys.dm_sql_referenced_entities ('Production.ApprovedDocuments', 'OBJECT');
GO
EXEC sp_rename 'Production.Document.ChangeNumber', 'TrackingNumber', 'COLUMN';
GO
SELECT referenced_schema_name AS schema_name
    ,referenced_entity_name AS table_name
    ,referenced_minor_name AS referenced_column
FROM sys.dm_sql_referenced_entities ('Production.ApprovedDocuments', 'OBJECT');
GO

La query restituisce i messaggi di errore seguenti:

Msg 207, Level 16, State 1, Procedure ApprovedDocuments, Line 3

Invalid column name 'ChangeNumber'.

Msg 2020, Level 16, State 1, Line 1

The dependencies reported for entity "Production.ApprovedDocuments" do not include references to columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.

Nell'esempio seguente viene corretto il nome della colonna nella vista.

USE AdventureWorks2008R2;
GO
ALTER VIEW Production.ApprovedDocuments
AS
    SELECT Title,TrackingNumber, Status
    FROM Production.Document
    WHERE Status = 2;
GO

Le dipendenze a livello di colonna non verranno restituite per le istruzioni all'interno di stored procedure contenenti join a tabelle temporanee. Per le stored procedure costituite da più istruzioni vengono restituite le dipendenze a livello di colonna per le istruzioni prive di join a una tabella temporanea. Per le istruzioni con join a una tabella temporanea non è disponibile una funzionalità per la restituzione di dipendenze a livello di colonna.

La colonna is_ambiguous restituisce valori incoerenti per le funzioni definite dall'utente

È possibile che il valore restituito nella colonna is_ambiguous sia incoerente per le funzioni definite dall'utente. La colonna is_ambiguous nella vista del catalogo sys.sql_expression_dependencies e nella funzione dinamica sys.dm_sql_referenced_entities indica che il riferimento all'entità è ambiguo, ovvero l'entità può essere risolta in fase di esecuzione in una funzione definita dall'utente, in un tipo definito dall'utente (UDT) o in un riferimento XQuery a una colonna di tipo xml. A seconda di come viene fatto riferimento alla funzione definita dall'utente, il tipo di entità può o non può essere chiaro, facendo sì che la colonna is_ambiguous venga impostata su 1 (true) in un caso e su 0 (false) nell'altro. Si consideri ad esempio la seguente stored procedure.

CREATE PROCEDURE dbo.p1 
AS
    SELECT Sales.GetOrder() FROM t1;
    SELECT Sales.GetOrder();

Nella prima istruzione SELECT non è chiaro se Sales.GetOrder() sia una funzione definita dall'utente nello schema Sales o una colonna denominata Sales di tipo definito dall'utente (UDT) con un metodo denominato GetOrder(). In questo caso, la colonna is_ambiguous verrà impostata su 1 per l'entità Sales.GetOrder() a cui si fa riferimento. Nella seconda istruzione SELECT il riferimento a Sales.GetOrder() è chiaro. In base alla sintassi, può essere solo un riferimento a una funzione definita dall'utente. In questo caso la colonna is_ambiguous viene impostata su 0. In base a questo comportamento il valore restituito nella colonna is_ambiguous potrebbe risultare incoerente. Capire il modo in cui viene determinato il valore della colonna is_ambiguous può contribuire a chiarire i valori restituiti.

La colonna is_ambiguous viene impostata su 0 (false) quando:

  • Risulta chiaro che il riferimento è a una funzione definita dall'utente, ovvero la query viene associata a una funzione definita dall'utente e un metodo UDT della colonna o una colonna di tipo xml con tale nome non esiste.

  • Risulta chiaro che il riferimento è a un metodo UDT della colonna, ovvero una colonna con tale metodo UDT esiste e una funzione definita dall'utente o una colonna di tipo xml con tale nome non esiste.

La colonna is_ambiguous viene impostata su 1 (true) quando:

  • Una funzione definita dall'utente, un metodo UDT della colonna o una colonna di tipo xml con il nome a cui si fa riferimento non esiste.

  • Il nome a cui si fa riferimento esiste per più entità. Ad esempio, una funzione definita dall'utente e un metodo UDT della colonna hanno lo stesso nome.

Per le entità di natura ambigua è possibile che le colonne referenced_database_name e referenced_schema_name non siano valide. Si consideri ad esempio la seguente funzione definita dall'utente:

CREATE FUNCTION GetNextEmpHierarchyId (@empname varchar(25))
RETURNS hierarchyid
AS
BEGIN
    RETURN 
(
    SELECT h.empid.GetDescendant((SELECT MAX(h1.empid)  
                                  FROM dbo.Employees AS h1  
                                  WHERE h1.empid.GetAncestor(1) = h.empid), NULL)
    FROM dbo.Employees AS h  
    WHERE h.empname = @empname  
)  
END;

Le colonne referenced_database_name e referenced_schema_name non saranno valide per la funzione a causa delle chiamate al metodo UDT hierarchyid. Non è chiaro se i riferimenti a h.empid.GetDescendant e h1.empid.GetAncestor siano riferimenti a un'entità mediante un nome composto da tre parti (database.schema.object) o a un metodo UDT (table.column.method).

Soluzione

Non è necessaria alcuna azione da parte dell'utente.

La colonna referenced_id non viene restituita per le dipendenze tra database

La colonna referenced_id non viene mai risolta per i riferimenti tra database nella vista del catalogo sys.sql_expression_dependencies. Il nome del database e il nome dello schema vengono registrati solo quando il nome viene specificato in modo esplicito. Quando ad esempio si specifica MyDB.MySchema.MyTable, vengono registrasti i nomi del server e del database, mentre quando si specifica MyDB..MyTable, viene registrato solo il nome del database.

La colonna referenced_id viene restituita per i riferimenti tra database nella funzione di sistema sys.dm_sql_referenced_entities solo quando è possibile associare correttamente l'entità a cui si fa riferimento. L'associazione potrebbe non riuscire per vari motivi che includono le cause seguenti:

  • Il database è offline.

  • L'entità a cui si fa riferimento non esiste nel database.

Soluzione

Verificare che il database sia online e che l'entità a cui si fa riferimento esista nel database.

La colonna referenced_id è NULL per le entità a cui si fa riferimento all'interno del database

La funzione di sistema sys.dm_sql_referenced_entities e la vista di sistema sys.sql_expression_dependencies restituiranno l'ID di tutte le entità associate a schema a cui si fa riferimento. La colonna referenced_id sarà tuttavia NULL per i riferimenti non associati a schema all'interno del database quando non è possibile determinare l'ID dell'entità a cui si fa riferimento. Questo può verificarsi nei seguenti casi:

  • L'entità a cui si fa riferimento non esiste nel database.

  • La risoluzione dei nomi è dipendente dal chiamante. In questo caso la colonna is_caller_dependent viene impostata su 1.

Soluzione

Verificare che l'entità a cui si fa riferimento esista nel database. Creare l'entità se non viene trovata oppure, se l'entità esiste, verificare che vengano soddisfatti i requisiti seguenti:

  • L'ortografia del nome dell'entità a cui si fa riferimento è corretta.

  • Il nome specificato soddisfa i requisiti delle regole di confronto del database. Se nel database vengono utilizzate regole di confronto con distinzione tra maiuscole e minuscole, il nome specificato deve corrispondere all'esatta combinazione di maiuscole e minuscole del nome dell'oggetto. Ad esempio, l'ID di un oggetto denominato SalesHistory non verrà trovato in un database con regole di confronto con distinzione tra maiuscole e minuscole se si specifica saleshistory.

  • Venga specificato il nome dello schema dell'oggetto. È necessario specificare un nome in due parti (schema_name.object_name) se l'oggetto non è presente nello schema predefinito del chiamante, nello schema sys o nello schema dbo.

Modificare la definizione dell'entità a cui si fa riferimento per soddisfare i requisiti precedenti.

Se l'entità a cui si fa riferimento è dipendente dal chiamante, modificare la definizione dell'entità di riferimento specificando un nome in due parti per l'entità a cui si fa riferimento. Per ulteriori informazioni sui riferimenti dipendenti dal chiamante, vedere Report sulle dipendenze SQL.

Le informazioni sulle dipendenze non vengono restituite per gli oggetti nel database master

Per le entità definite dall'utente create nel database master vengono create e gestite le dipendenze SQL. Se per un'entità non vengono restituite le dipendenze SQL, effettuare le operazioni seguenti:

  • Assicurarsi che l'entità sia un tipo valido per il rilevamento delle dipendenze

    Le informazioni sulle dipendenze non vengono rilevate per tutti gli oggetti utente. Per un elenco dei tipi di entità per i quali vengono create e gestite le informazioni sulle dipendenze, vedere Informazioni sulle dipendenze SQL.

  • Assicurarsi che l'entità non sia contrassegnata come oggetto di sistema.

    Eseguire una query sulla colonna is_ms_shipped per l'entità nella vista del catalogo sys.objects. Se questa colonna è impostata su 1, l'entità è un oggetto di sistema fornito con SQL Server o un oggetto definito dall'utente modificato per riprodurre un oggetto di sistema impostando manualmente questa colonna su 1. 

Soluzione

Se l'oggetto è di un tipo che non è supportato, le informazioni sulle dipendenze non saranno disponibili.

Le dipendenze da oggetti di sistema non vengono rilevate. Se l'entità è definita dall'utente, reimpostare la colonna is_ms_shipped su 0 se si desidera creare e gestire le dipendenze per l'entità in SQL Server.