Partilhar via


Solucionando problemas de visibilidade de metadados de exibições particionadas distribuídas

Se um usuário de baixo privilégio tentar inserir, atualizar ou excluir dados através de uma exibição particionada distribuída, o SQL Server irá gerar o seguinte erro:

Erro 4436 "A exibição UNION ALL '%.*ls' não é atualizável porque não foi encontrada uma coluna de particionamento".

Esse problema não afeta exibições particionadas localmente, como no caso de existirem tabelas subjacentes na mesma instância do SQL Server.

Segundo plano

No caso de consultas distribuídas, o SQL Server deve ser capaz de ler a definição SQL de restrições CHECK nas tabelas do servidor remoto (vinculado). Isso significa que o chamador de uma consulta distribuída deve ter permissão CONTROL, ALTER, TAKE OWNERSHIP ou VIEW DEFINITION na tabela remota. Se o chamador da consulta distribuída não tiver uma das permissões, a consulta irá falhar com o erro 4436.

ObservaçãoObservação

Se um usuário não tiver nenhuma dessas permissões, o valor da coluna definition em sys.check_constraints será NULL quando o usuário consultar o catálogo.

Para resolver o erro 4436

Para tornar a definição da restrição CHECK visível ao chamador, conceda-lhe VIEW DEFINITION em toda tabela de destino subjacente à exibição particionada distribuída.

Por exemplo, suponhamos que Server1 e Server2 sejam servidores federados e tenham sido definidos como servidores vinculados entre si. Suponhamos que master.dbo.t1 seja a tabela particionada que pode ser acessada por todos os membros da função de banco de dados dpv_users. Suponhamos que dpv_users contenha todos os usuários que têm acesso SELECT, INSERT, UPDATE e DELETE através da exibição particionada distribuída.

Execute o código a seguir em cada servidor vinculado.

CREATE TABLE t1(c INT PRIMARY KEY CHECK (...)) ; -- CHECK is different on each server.
GO

GRANT SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION ON t1 TO dpv_users ;
GO

CREATE VIEW the_dpv AS
    SELECT * FROM Server1.master.dbo.t1
    UNION ALL
    SELECT * FROM Server2.master.dbo.t1 
GO