Solucionando problemas de dependências do SQL

Este tópico descreve os problemas comuns de dependência de objetos e suas soluções.

A função de gerenciamento dinâmico sys.dm_sql_referenced_entities não retorna dependências de nível de coluna.

A função de sistema sys.dm_sql_referenced_entities reportará qualquer dependência de nível de coluna para referências associadas a esquema. Por exemplo, ela reportará todas as dependências em nível de coluna de uma exibição indexada porque uma exibição indexada exige uma associação de esquema. No entanto, quando a entidade referenciada não estiver associada a esquema, as dependências de coluna serão reportadas somente se todas as instruções com referência a essas colunas puderem ser associadas. Será possível associar as instruções com êxito somente se todos os objetos existirem no momento em que as instruções forem analisadas. Se alguma instrução definida na entidade não for associada, as dependências de coluna não serão reportadas e a coluna referenced_minor_id retornará 0. Quando não for possível resolver as dependências de coluna, ocorrerá o erro 2020. Esse erro não evita que a consulta retorne dependências no nível de objeto.

Solução

Corrija os erros identificados na mensagem antes do erro 2020. Por exemplo, no exemplo de código a seguir, a exibição Production.ApprovedDocuments é definida nas colunas Title, ChangeNumber e Status da tabela Production.Document. A função de sistema sys.dm_sql_referenced_entities é consultada sobre os objetos e as colunas das quais a exibição ApprovedDocuments depende. Como a exibição não foi criada com o uso da cláusula WITH SCHEMA_BINDING, as colunas referenciadas na exibição poderão ser modificadas na tabela da referência. O exemplo altera a coluna ChangeNumber da tabela Production.Document, renomeando-a para TrackingNumber. A exibição ApprovedDocuments é consultada novamente na exibição do catálogo; contudo, não é possível associar todas as colunas definidas na exibição. São retornados os erros 207 e 2020 que identificam o problema. Para resolver o problema, a exibição deve ser alterada de modo a refletir o novo nome da coluna.

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

A consulta retorna as seguintes mensagens de erro.

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.

O exemplo a seguir corrige o nome da coluna na exibição.

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

As dependências de nível de coluna não serão retornadas para as instruções dos procedimentos armazenados que contêm junções com tabelas temporárias. Para os procedimentos armazenados que consistem em várias instruções, as dependências no nível de coluna são retornadas para as instruções que não têm junções com uma tabela temporária. As instruções sem junção com uma tabela temporária não terão o recurso de relatório de dependência no nível de coluna.

A coluna is_ambiguous reporta valores inconsistentes para funções definidas pelo usuário

Pode parecer que o valor reportado na coluna is_ambiguous é inconsistente para funções definidas pelo usuário. A coluna is_ambiguous na exibição de catálogo sys.sql_expression_dependencies e a função dinâmica sys.dm_sql_referenced_entities indica que a referência à entidade é ambígua. Ou seja, a entidade pode ser resolvida em tempo de execução para uma função definida pelo usuário, um UDT (Tipo Definido pelo Usuário) ou uma referência XQuery para uma coluna do tipo xml. Dependendo de como a função definida pelo usuário é referenciada, o tipo de entidade pode ou não ser claro, o que pode fazer com que a coluna is_ambiguous seja definida como 1 (true) em um caso e como 0 (false) em outro. Por exemplo, considere o procedimento armazenado a seguir.

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

Na primeira instrução SELECT, não está claro se Sales.GetOrder() é uma função definida pelo usuário no esquema Sales ou uma coluna denominada Sales do tipo UDT com um método denominado GetOrder(). Nesse caso, a coluna is_ambiguous será definida como 1 para a entidade referenciada Sales.GetOrder(). Na segunda instrução SELECT, a referência a Sales.GetOrder() é clara; com base na sintaxe, ela só pode ser uma referência a uma função definida pelo usuário. Nesse caso, a coluna is_ambiguous será definida como 0. Esse comportamento pode fazer com que pareça que o valor reportado na coluna is_ambiguous é inconsistente. Saber como o valor da coluna is_ambiguous é determinado pode esclarecer os valores reportados.

A coluna is_ambiguous será definida como 0 (false) quando:

  • Estiver claro que a referência é a uma função definida pelo usuário. Ou seja, a consulta está associada a uma função definida pelo usuário e a coluna do método UDT ou de tipo xml com esse nome não existe.

  • Estiver claro que a referência é a um método UDT de coluna. Ou seja, a consulta com esse método UDT existe e uma função definida pelo usuário ou uma coluna do tipo xml com esse nome não existe.

A coluna is_ambiguous será definida como 1 (true) quando:

  • Uma função definida pelo usuário, um método UDT de coluna ou uma coluna do tipo xml com o nome referenciado não existir.

  • O nome referenciado existir para várias entidades. Por exemplo, uma função definida pelo usuário e um método UDT de coluna têm o mesmo nome.

Para entidades que são ambíguas por natureza, é possível que as colunas referenced_database_name e referenced_schema_name sejam inválidas. Por exemplo, considere a seguinte função definida pelo usuário:

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;

As colunas referenced_database_name e referenced_schema_name serão inválidas para a função devido às chamadas do método UDT hierarchyid. Não está claro que as referências a h.empid.GetDescendant e h1.empid.GetAncestor são referências de uma entidade que usa um nome de três partes (database.schema.object) ou a um método UDT (table.column.method).

Solução

Nenhuma ação de usuário é necessária.

A coluna referenced_id não é reportada para dependências entre banco de dados.

A coluna referenced_id nunca é resolvida para referências entre bancos de dados na exibição de catálogo sys.sql_expression_dependencies. Os nomes do banco de dados e do esquema serão registrados apenas quando forem explicitamente especificados. Por exemplo, quando especificados como MyDB.MySchema.MyTable, os nomes do banco de dados e do esquema são registrados; no entanto, quando especificados como MyDB..MyTable, somente o nome do banco de dados é registrado.

A referenced_id é reportada em referências entre bancos de dados na função de sistema sys.dm_sql_referenced_entities somente quando a entidade referenciada pode ser associada com êxito. A associação pode falhar por diversos motivos, incluindo:

  • O banco de dados está offline.

  • A entidade referenciada não existe no banco de dados.

Solução

Verifique se o banco de dados está online e se a entidade referenciada existe no banco de dados.

A coluna referenced_id é nula para entidades referenciadas do banco de dados.

A função de sistema sys.dm_sql_referenced_entities e a exibição de sistema sys.sql_expression_dependencies reportará a ID de qualquer entidade referenciada associada a esquema. No entanto, a coluna referenced_id é NULL para referências associadas a esquema no banco de dados quando a ID da entidade referenciada não puder ser determinada. Isso pode ocorrer quando:

  • A entidade referenciada não existe no banco de dados.

  • A resolução do nome depende do chamador. Nesse caso, a coluna is_caller_dependent é definida como 1.

Solução

Verifique se a entidade referenciada existe no banco de dados. Crie a entidade se ela não for encontrada ou, se ela existir, confirme se satisfaz estes critérios:

  • O nome da entidade referenciada foi digitado corretamente.

  • O nome especificado satisfaz os requisitos de agrupamento do banco de dados. Se o banco de dados usar um agrupamento com diferenciação de maiúsculas e minúsculas, o nome especificado deverá corresponder exatamente ao uso de maiúsculas e minúsculas no nome do objeto. Por exemplo, a ID de um objeto denominado SalesHistory não será encontrada no banco de dados com agrupamento com diferenciação de maiúsculas e minúsculas se for especificado como saleshistory.

  • O nome do esquema do objeto foi especificado. Um nome de duas partes (schema_name.object_name) será necessário se o objeto não estiver no esquema padrão do chamador, no esquema sys ou no esquema dbo.

Modifique a definição da entidade referenciada para satisfazer os requisitos anteriores.

Se a entidade que faz referência depende do chamador, modifique sua definição especificando um nome de duas partes para a entidade referenciada. Para obter mais informações sobre referências que dependem do chamador, consulte Informando dependências de SQL.

As informações de dependência não são reportadas para objetos do banco de dados mestre

As dependências SQL das entidades definidas pelo usuário criadas no banco de dados master são criadas e mantidas. Se as dependências do SQL de uma entidade não forem relatadas, siga estas etapas:

  • Confirme se a entidade é um tipo válido para a controle de dependência.

    As informações de dependência não são controladas para todos os objetos do usuário. Para ver uma lista de tipos de entidade cujas informações de dependência são criadas e mantidas, consulte Compreendendo dependências do SQL.

  • Confirme se a entidade não está marcada como objeto do sistema.

    Consulte a coluna is_ms_shipped da entidade na exibição de catálogo sys.objects. Se essa coluna estiver definida como 1, a entidade será um objeto de sistema que acompanha o SQL Server ou um objeto definido pelo usuário que foi modificado para imitar um objeto de sistema pela configuração manual dessa coluna como 1. 

Solução

Se o objeto for de um tipo sem suporte, as informações de dependência não estarão disponíveis.

Não são controladas as dependências em objetos de sistema. Se a entidade for definida pelo usuário, a is_ms_shipped column deverá ser redefinida para 0 se você quiser que o SQL Server crie e mantenha dependências na entidade.