Bagaimana saya bisa mendeteksi prosedur tersimpan yang rusak setelah perubahan skema?

11

Saya telah memodifikasi tabel pusat dalam database saya, dan sp_depends benar-benar mengembalikan ratusan hasil, dan saya khawatir beberapa prosedur tersimpan mungkin tidak dapat dikompilasi lagi setelah perubahan saya.

Memeriksa satu prosedur tersimpan tunggal itu mudah (saya hanya menjalankan kembali skrip alter dan melihat apakah operasi berhasil), tetapi melakukan itu pada 100+ prosedur agak rumit.

Saya tahu saya bisa menggunakan skrip seperti ini untuk mengkompilasi ulang semua objek dari database saya, tetapi operasi yang sebenarnya akan terjadi pada saat prosedur tersimpan dijalankan, tidak segera, sehingga sepertinya tidak sesuai dalam kasus saya.

Saya juga berpikir bahwa saya dapat membuang semua prosedur yang tersimpan secara bersamaan, dan melakukan resycnhronize basis data saya dengan sistem kendali sumber saya, tetapi opsi itu, meskipun dapat dijalankan, tidak terlalu elegan. Apakah ada cara yang lebih baik untuk melakukan ini?

Saya menggunakan SQLServer 2008 R2 dan skrip basis data saya disimpan dalam proyek basis data VS 2008.


Untuk memperjelas, saya tidak menganjurkan orang harus semata-mata mengandalkan pendekatan ini untuk menguji kode. Persis seperti di c # Anda secara instan mendeteksi kesalahan sintaks dalam file dependen lain saat Anda kode (dan kemudian menggunakan strategi lain untuk menguji seperti unit test, yang biasanya beberapa urutan besarnya lebih lambat), saya pikir masuk akal untuk mendeteksi dependensi SQL kesalahan dalam hitungan detik daripada harus menjalankan tes fungsional penuh yang biasanya dapat memakan waktu beberapa jam untuk menyelesaikannya.

Brann
sumber

Jawaban:

7

Bagaimana kalau Anda menjalankan tes unit, fungsional, integrasi, dan kinerja Anda? Jika Anda tidak memiliki tes apa pun maka ini adalah waktu yang serius untuk mulai mempertimbangkan skema basis data Anda sebagai kode dan memperlakukannya seperti itu, termasuk kontrol versi dan pengujian. Alex Kuznetsov memiliki seluruh buku yang didedikasikan untuk subjek ini: Pemrograman Basis Data Defensif dengan SQL Server .

Remus Rusanu
sumber
Tes tidak selalu mencakup 100% dari kode, dan ketika mereka melakukannya biasanya memerlukan beberapa jam untuk menjalankannya. Dalam c #, saya dapat mendeteksi apakah kode saya masih dikompilasi dalam hitungan detik (terlepas dari kebenarannya). Ini tidak berarti saya harus mendorong kode (terlepas dari kode yang menjadi c # atau PLSQL) ke dalam produksi tanpa mengujinya dengan benar, tetapi tampaknya tidak masuk akal untuk memiliki cara cepat mendeteksi dependensi yang rusak, bukan?
Brann
2
Sayangnya keadaan SQL Server saat ini vis-a-vis deteksi ketergantungan dalam prosedur tersimpan adalah 'sangat rusak', lihat Memahami Ketergantungan SQL atau Menjaga agar selalu diperbarui di SQL Server 2008 . Bahkan ada alat pihak ketiga yang mencoba mengatasi masalah ini
Remus Rusanu
2
Ini membuat tes unit / fungsional cukup satu-satunya cara yang dapat diandalkan untuk mendeteksi perubahan yang melanggar.
Remus Rusanu
1
Untuk pemeriksaan cepat Proyek Database Visual Studio melakukan pekerjaan yang cukup baik dalam memvalidasi setiap perubahan.
Remus Rusanu
4

Ini pekerjaan yang sulit, tetapi Anda dapat membuat skrip CREATE PROSEDUR untuk basis data (klik kanan basis data -> tugas -> menghasilkan skrip), temukan dan ganti CREATE PROCEDURE dengan ALTER PROCEDURE, kemudian parse.

Saya harap Anda mendapatkan jawaban yang lebih baik di sini - Saya juga tertarik! :)

JHFB
sumber
Saya tidak menandai jawaban Anda yang diterima karena saya masih berharap untuk solusi yang lebih bersih (semoga yang bisa dituliskan), tetapi Anda pasti mendapatkan +1 saya! Terima kasih.
Brann
3
Pendekatan ini tidak akan memberi tahu Anda jika Anda mereferensikan tabel yang tidak ada .
Nick Chammas
Pendekatan ini juga tidak akan berfungsi jika skrip yang dihasilkan lebih besar dari sekitar 30k baris. Aku benci kalau aku tahu ini ..
Eonasdan
3

Anda dapat menggunakan Sql Server Data Tools (SSDT). Microsoft Visual Studio memungkinkan Anda untuk membuat proyek Server Sql. Satu kemudian mengimpor database ke dalam proyek dan kemudian membangun proyek. Jika ada prosedur atau objek tersimpan yang rusak, Anda akan mendapatkan kesalahan kompilasi.

VenVig
sumber
Saya akan menambahkan bahwa Anda dapat dengan mudah membuat skrip pembuatan basis data baru dari proyek SSDT dan berjalan dalam lingkungan pengujian, yang akan menjadi verifikasi yang cukup menyeluruh bahwa tidak ada procs / pemicu / dll yang rusak karena perubahan skema.
AaronLS
3

Anda mungkin ingin melihat pertanyaan SO ini Saya sedang mencari cara yang dapat diandalkan untuk memverifikasi prosedur tersimpan T-SQL. Adakah yang punya? yang pada dasarnya menanyakan hal yang sama, dengan beberapa jawaban.

Untuk membuat skrip Alaa Awad diposting ... ini harus menunjukkan skema dan database objek yang direferensikan dan referensi. Jika Anda menggunakan banyak tabel temp melalui alias (yang terkadang muncul saat menggunakan sys.sql_expression_dependencies), parameter UDTT atau fitur dinamis lainnya Anda mungkin perlu menggunakan fungsi sys.dm_sql_referenced_entitiesatau sys.dm_sql_referencing_entitiessebagai gantinya / juga.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]
Arkaine55
sumber
1
Harus menambahkan ini ke klausa mana: / * Bukan UserType yang ada / DAN sed.referenced_entity_name TIDAK DI (PILIH [nama] DARI sys.types) / Bukan alias * / DAN sed.referenced_schema_name BUKAN NULL
JasonBluefire
1

gunakan sys.sql_expression_dependencies ditambahkan dalam sql server 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO
Alaa Awad
sumber
Ini mungkin berguna, namun tidak sesederhana skema ini juga perlu mempertimbangkan. Saya juga mendapatkan masalah di mana sys.sql_expession_dependencies menampilkan alias yang digunakan daripada tabel dependen yang sebenarnya, yang jelas gagal dalam tes object_id (). Akhirnya memunculkan tabel yang ditetapkan pengguna sebagai parameter untuk prosedur tersimpan - yang tidak terlalu berguna.
Tabloo Quijico