Estoy escribiendo un procedimiento almacenado que toma el nombre de una base de datos como argumento y devuelve una tabla de los índices de esa base de datos y su nivel de fragmentación. Este procedimiento almacenado vivirá en nuestra base de datos DBA (el DB que contiene tablas que los DBA usan para monitorear y optimizar cosas). Los sistemas en cuestión son todos SQL Server 2008 R2 si eso marca la diferencia.
Tengo la consulta básica resuelta, pero estoy atascado en tratar de proporcionar los nombres reales de los índices. Que yo sepa, esa información está contenida en la vista sys.indexes de cada individuo. Mi problema específico es tratar de hacer referencia a esa vista mediante programación desde el procedimiento almacenado de otra base de datos.
Para ilustrar, esta es la parte de la consulta en cuestión:
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
La consulta funciona bien cuando se ejecuta desde la base de datos identificada por @db_id, porque está utilizando la vista sys.indexes adecuada. Sin embargo, si trato de llamar a esto desde la base de datos DBA, todo se vuelve nulo, ya que la vista sys.indexes es para la base de datos incorrecta.
En términos más generales, necesito poder hacer algo como esto:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
o
USE @db_name;
He intentado cambiar bases de datos o hacer referencia a otras bases de datos utilizando combinaciones de concatenación de cadenas y funciones OBJECT_NAME / OBJECT_ID / DB_ID y nada parece funcionar. Apreciaría cualquier idea que la comunidad pueda tener, pero sospecho que tendré que actualizar este procedimiento almacenado para residir en cada base de datos individual.
Gracias de antemano por cualquier sugerencia.
fuente
Respuestas:
El SQL dinámico es útil para este tipo de tareas administrativas. Aquí hay un fragmento de un procedimiento almacenado que escribí que no solo obtiene los niveles de desfragmentación, sino que también genera el código para realizar la desfragmentación:
fuente
La alternativa al SQL dinámico es SQLCMD , que se puede invocar desde la línea de comandos, un paso de trabajo del agente, el cmdlet Invoke-Sqlcmd Powershell o habilitado en SSMS . Su ejemplo en la sintaxis SQLCMD sería:
El modo SQLCMD es una de esas características que desearía haber conocido antes. Práctico en muchas situaciones.
fuente
Por lo general, es difícil hacer referencia a un conjunto de tablas de un procedimiento contenido en una base de datos diferente. Si instala su procedimiento en Master, como un procedimiento del sistema, puede usarse en otros contextos de base de datos sin intentar referirse a sí mismo.
Creo que: si su procedimiento comienza con 'sp_', entonces se vuelve universalmente visible, y si lo define en el esquema 'sys.sp_%', puede usarse en otros contextos de base de datos.
Esto proporcionaría una forma alternativa de operar en múltiples bases de datos sin tener que conectar dinámicamente el DB_name.
fuente