Ich schreibe eine gespeicherte Prozedur, die einen Datenbanknamen als Argument verwendet und eine Tabelle der Indizes dieser Datenbank und ihrer Fragmentierungsstufe zurückgibt. Diese gespeicherte Prozedur befindet sich in unserer DBA-Datenbank (der Datenbank, die Tabellen enthält, die die DBAs zur Überwachung und Optimierung verwenden). Bei den fraglichen Systemen handelt es sich ausschließlich um SQL Server 2008 R2, wenn dies einen Unterschied macht.
Ich habe die grundlegende Abfrage ausgearbeitet, versuche aber nicht, die tatsächlichen Namen der Indizes anzugeben. Nach meinem besten Wissen sind diese Informationen in der sys.indexes-Ansicht jedes Einzelnen enthalten. Mein spezifisches Problem besteht darin, diese Ansicht programmgesteuert aus der gespeicherten Prozedur einer anderen Datenbank heraus zu referenzieren.
Zur Veranschaulichung ist dies der Teil der fraglichen Abfrage:
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
Die Abfrage funktioniert einwandfrei, wenn sie aus der durch @db_id angegebenen Datenbank ausgeführt wird, da sie die richtige Ansicht sys.indexes verwendet. Wenn ich versuche, dies aus der DBA-Datenbank aufzurufen, wird jedoch alles null angezeigt, da die Ansicht sys.indexes für die falsche Datenbank ist.
Allgemeiner gesagt muss ich in der Lage sein, so etwas zu tun:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
oder
USE @db_name;
Ich habe versucht, Datenbanken zu wechseln oder andere Datenbanken mit Kombinationen aus Zeichenfolgenverkettung und OBJECT_NAME / OBJECT_ID / DB_ID-Funktionen zu referenzieren, und nichts scheint zu funktionieren. Ich würde mich über Ideen der Community freuen, aber ich vermute, dass ich diese gespeicherte Prozedur umrüsten muss, um sie in jeder einzelnen Datenbank zu speichern.
Vielen Dank im Voraus für alle Vorschläge.
quelle
Antworten:
Dynamic SQL ist praktisch für diese Art von Verwaltungsaufgaben. Hier ist ein Ausschnitt aus einer gespeicherten Prozedur, die ich geschrieben habe und die nicht nur die Defragmentierungsstufen abruft, sondern auch den Code für die Defragmentierung generiert:
quelle
Die Alternative zu dynamischem SQL ist SQLCMD , das über die Befehlszeile, einen Agentenjobschritt , das Cmdlet Invoke-Sqlcmd Powershell oder in SSMS aktiviert aufgerufen werden kann . Ihr Beispiel in der SQLCMD-Syntax wäre:
Der SQLCMD-Modus ist eine der Funktionen, von denen ich mir wünschte, ich hätte sie früher gewusst. Praktisch in vielen Situationen.
quelle
Es ist normalerweise schwierig, einen Satz von Tabellen aus einer Prozedur zu referenzieren, die in einer anderen Datenbank enthalten ist. Wenn Sie Ihre Prozedur in Master als Systemprozedur installieren, kann sie in anderen DB-Kontexten verwendet werden, ohne dass versucht wird, auf sich selbst zurückzugreifen.
Ich denke das: Wenn Ihre Prozedur mit 'sp_' beginnt, wird sie allgemein sichtbar, und wenn Sie sie im Schema 'sys.sp_%' definieren, kann sie in anderen DB-Kontexten verwendet werden.
Dies würde eine alternative Möglichkeit bieten, in mehreren DBs zu arbeiten, ohne den DB-Namen dynamisch einstecken zu müssen.
quelle