J'écris une procédure stockée qui prend un nom de base de données comme argument et renvoie une table des index de cette base de données et leur niveau de fragmentation. Cette procédure stockée vivra dans notre base de données DBA (la base de données qui contient les tables que les DBA utilisent pour surveiller et optimiser les choses). Les systèmes en question sont tous SQL Server 2008 R2 si cela fait une différence.
J'ai la requête de base élaborée, mais je suis coincé à essayer de fournir les noms réels des index. À ma connaissance, cette information est contenue dans la vue sys.indexes de chaque individu. Mon problème spécifique essaie de référencer cette vue par programme à partir d'une procédure stockée d'une autre base de données.
Pour illustrer, voici la partie de la requête en cause:
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 requête fonctionne correctement lorsqu'elle est exécutée à partir de la base de données identifiée par @db_id, car elle utilise la vue sys.indexes appropriée. Si j'essaie d'appeler cela à partir de la base de données DBA, cependant, tout est nul, car la vue sys.indexes est pour la mauvaise base de données.
De manière plus générale, je dois pouvoir faire quelque chose comme ceci:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
ou
USE @db_name;
J'ai essayé de changer de base de données ou de référencer d'autres bases de données en utilisant des combinaisons de concaténation de chaînes et de fonctions OBJECT_NAME / OBJECT_ID / DB_ID et rien ne semble fonctionner. J'apprécierais toutes les idées que la communauté pourrait avoir, mais je soupçonne que je devrai réorganiser cette procédure stockée pour résider dans chaque base de données individuelle.
Merci d'avance pour toute suggestion.
la source
Réponses:
Dynamic SQL est pratique pour ces types de tâches administratives. Voici un extrait d'une procédure stockée que j'ai écrite qui non seulement obtient les niveaux de défragmentation, mais génère également le code pour effectuer la défragmentation:
la source
L'alternative au SQL dynamique est SQLCMD , qui peut être invoquée à partir de la ligne de commande, une étape de travail d'agent, la cmdlet Invoke-Sqlcmd Powershell ou activée dans SSMS . Votre exemple dans la syntaxe SQLCMD serait:
Le mode SQLCMD est l'une de ces fonctionnalités que j'aurais aimé connaître plus tôt. Pratique dans de nombreuses situations.
la source
Il est généralement difficile de référencer un ensemble de tables à partir d'une procédure contenue dans une base de données différente. Si vous installez votre procédure dans Master, en tant que procédure système, elle peut être utilisée dans d'autres contextes de base de données sans essayer de se référer à elle-même.
Je pense que: si votre procédure commence par 'sp_' alors elle devient universellement visible, et si vous la définissez dans le schéma 'sys.sp_%', alors elle peut être utilisée dans d'autres contextes DB.
Cela fournirait un autre moyen de fonctionner dans plusieurs bases de données sans avoir à brancher dynamiquement le nom_db.
la source