Estou escrevendo um procedimento armazenado que usa um nome de banco de dados como argumento e retorna uma tabela dos índices desse banco de dados e seu nível de fragmentação. Este procedimento armazenado permanecerá em nosso banco de dados DBA (o banco de dados que contém tabelas que os DBAs usam para monitorar e otimizar as coisas). Os sistemas em questão são todos do SQL Server 2008 R2, se isso faz diferença.
Eu tenho a consulta básica elaborada, mas estou tentando fornecer os nomes reais dos índices. Que eu saiba, essas informações estão contidas na exibição de sys.indexes de cada indivíduo. Meu problema específico é tentar referenciar essa exibição programaticamente do procedimento armazenado de outro banco de dados.
Para ilustrar, esta é a parte da consulta em questão:
FROM sys.dm_db_index_physical_stats(@db_id,NULL,NULL,NULL,NULL) p
INNER JOIN sys.indexes b ON p.[object_id] = b.[object_id]
AND p.index_id = b.index_id
AND b.index_id != 0
A consulta funciona bem quando executada no banco de dados identificado por @db_id, porque está usando a exibição sys.indexes adequada. Se eu tentar chamar isso do banco de dados DBA, no entanto, tudo será nulo, pois a exibição sys.indexes é para o banco de dados errado.
Em termos mais gerais, eu preciso ser capaz de fazer algo assim:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
ou
USE @db_name;
Tentei alternar bancos de dados ou fazer referência a outros bancos de dados usando combinações de concatenação de strings e funções OBJECT_NAME / OBJECT_ID / DB_ID e nada parece funcionar. Aprecio todas as idéias que a comunidade possa ter, mas suspeito que precisarei refazer esse procedimento armazenado para residir em cada banco de dados individual.
Agradecemos antecipadamente por quaisquer sugestões.
fonte
Respostas:
O SQL dinâmico é útil para esses tipos de tarefas administrativas. Aqui está um trecho de um procedimento armazenado que escrevi que não apenas obtém os níveis de desfragmentação, mas também gera o código para fazer a desfragmentação:
fonte
A alternativa ao SQL dinâmico é o SQLCMD , que pode ser chamado na linha de comando, em uma etapa da tarefa do agente, no cmdlet Invoke-Sqlcmd Powershell ou ativado no SSMS . Seu exemplo na sintaxe do SQLCMD seria:
O modo SQLCMD é um desses recursos que eu gostaria de conhecer antes. Útil em muitas situações.
fonte
Geralmente é difícil fazer referência a um conjunto de tabelas de um procedimento contido em um banco de dados diferente. Se você instalar o procedimento no Master, como um procedimento do sistema, ele poderá ser usado em outros contextos do banco de dados sem tentar se referir a si próprio.
Penso que: se o seu procedimento começar com 'sp_', ele se tornará universalmente visível e, se você o definir no esquema 'sys.sp_%', poderá ser usado em outros contextos de banco de dados.
Isso forneceria uma maneira alternativa de operar em vários bancos de dados sem a necessidade de conectar o DB_name dinamicamente.
fonte