Saya menulis prosedur tersimpan yang menggunakan nama database sebagai argumen dan mengembalikan tabel indeks basis data dan tingkat fragmentasi mereka. Prosedur tersimpan ini akan hidup di basis data DBA kami (DB yang berisi tabel yang digunakan DBA untuk memantau dan mengoptimalkan hal-hal). Sistem yang dimaksud adalah semua SQL Server 2008 R2 jika itu membuat perbedaan.
Saya memiliki kueri dasar yang berhasil, tetapi saya terjebak mencoba memberikan nama aktual indeks. Sepengetahuan saya, informasi itu terkandung dalam pandangan sys.indexes masing-masing individu. Masalah khusus saya adalah mencoba untuk mereferensikan pandangan yang terprogram dari prosedur tersimpan database lain.
Sebagai ilustrasi, ini adalah bagian dari pertanyaan yang dipermasalahkan:
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
Permintaan bekerja dengan baik ketika dieksekusi dari database yang diidentifikasi oleh @db_id, karena menggunakan tampilan sys.indexes yang tepat. Namun, jika saya mencoba untuk memanggil ini dari database DBA, semuanya muncul nol, karena tampilan sys.indexes adalah untuk database yang salah.
Dalam istilah yang lebih umum, saya harus dapat melakukan sesuatu seperti ini:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
atau
USE @db_name;
Saya telah mencoba mengalihkan basis data atau mereferensikan basis data lain dengan menggunakan kombinasi rangkaian string dan fungsi OBJECT_NAME / OBJECT_ID / DB_ID dan sepertinya tidak ada yang berhasil. Saya menghargai ide apa pun yang mungkin dimiliki komunitas, tetapi saya curiga saya harus memperlengkapi kembali prosedur tersimpan ini untuk berada di setiap basis data individu.
Terima kasih sebelumnya atas saran Anda.
sumber
Jawaban:
SQL dinamis sangat berguna untuk jenis tugas administrasi ini. Berikut ini cuplikan dari prosedur tersimpan yang saya tulis yang tidak hanya mendapatkan level defragmentasi, tetapi juga menghasilkan kode untuk melakukan defragmentasi:
sumber
Alternatif untuk SQL dinamis adalah SQLCMD , yang dapat dipanggil dari baris perintah, langkah pekerjaan agen, cmdlet Invoke-Sqlcmd Powershell atau diaktifkan di SSMS . Contoh Anda dalam sintaks SQLCMD adalah:
Mode SQLCMD adalah salah satu fitur yang ingin saya ketahui sebelumnya. Berguna dalam banyak situasi.
sumber
Biasanya sulit untuk merujuk satu set tabel dari prosedur yang terdapat dalam DB yang berbeda. Jika Anda menginstal prosedur Anda di Master, sebagai prosedur sistem, maka prosedur ini dapat digunakan dalam konteks DB lainnya tanpa mencoba merujuk kembali ke prosedur itu sendiri.
Saya berpikir bahwa: jika prosedur Anda dimulai dengan 'sp_' maka itu menjadi terlihat secara universal, dan jika Anda mendefinisikannya dalam skema 'sys.sp_%', maka itu dapat digunakan dalam konteks DB lainnya.
Ini akan memberikan cara alternatif untuk beroperasi dalam banyak DB tanpa harus mencolokkan DB_name secara dinamis.
sumber