Cara memperbarui Majelis CLR tanpa menjatuhkan perakitan dari SQL Server

18

Bagaimana saya bisa memperbarui dll fungsi CLR (atau prosedur) perakitan tanpa harus menjatuhkan dan membuat ulang perakitan di SQL Server (2008 R2)?

Seperti berdiri sekarang jika saya memperbarui majelis (misalnya untuk menambah fungsi baru), SQL Server tidak akan menghormati dll diperbarui sampai saya jatuhkan majelis:

DROP ASSEMBLY CLRFunctions

Msg 6590, Level 16, State 1, Line 1
DROP ASSEMBLY failed because 'CLRFunctions' is referenced by object 'NormalizeString'.

Tetapi sebelum saya dapat menghentikan perakitan, saya harus terlebih dahulu menghapus semua fungsi yang merujuknya:

DROP FUNCTION NormalizeString
DROP FUNCTION RemoveDiacritics
DROP FUNCTION RemoveCombiningDiacritics
DROP FUNCTION CombineLigatures
....
DROP FUNCTION PseudolocalizeArabic

Dan kemudian saya bisa menjatuhkan perakitan:

DROP ASSEMBLY CLRFunctions

Sekarang saya harus " membuat " perakitan:

CREATE ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';

Dan sekarang saya harus berburu deklarasi semua UDF yang telah terdaftar sebelum saya dihapus mereka.

saya lebih suka memperbarui majelis, dan SQL Server mulai menggunakannya.


Pembaruan : saya mencoba secara acak DBCC FREEPROCCACHEuntuk memaksa "kompilasi ulang", tetapi SQL Server masih menggunakan kode lama.

Pembaruan : saya menghapus dll perakitan CLRFunctions.dll, dan SQL Server masih dapat menjalankan kode (tanpa kode yang seharusnya tidak mungkin).

Ian Boyd
sumber

Jawaban:

16

Saya pikir Anda sedang mencari alter assembly. Dari BOL:

Jika klausa FROM ditentukan, ALTER ASSEMBLY memperbarui perakitan sehubungan dengan salinan terbaru dari modul yang disediakan. Karena mungkin ada fungsi CLR, prosedur tersimpan, pemicu, tipe data, dan fungsi agregat yang ditentukan pengguna dalam contoh SQL Server yang sudah didefinisikan terhadap rakitan, pernyataan ALTER ASSEMBLY mengubah mereka ke implementasi terbaru rakitan. Untuk menyelesaikan rebinding ini, metode yang memetakan ke fungsi CLR, prosedur yang tersimpan, dan pemicu harus tetap ada dalam perakitan yang dimodifikasi dengan tanda tangan yang sama. Kelas yang mengimplementasikan tipe yang ditentukan pengguna CLR dan fungsi agregat yang ditentukan pengguna harus tetap memenuhi persyaratan untuk menjadi tipe atau agregat yang ditentukan pengguna.

Salah satu contoh di halaman yang sama sepertinya berhasil:

ALTER ASSEMBLY ComplexNumber 
FROM 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\1033\Engine\Programmability\CLR\UserDefinedDataType\CS\ComplexNumber\obj\Debug\ComplexNumber.dll' 
Ben Thul
sumber
1
Bisakah ini dilakukan ketika perakitan yang diperbarui terletak pada mesin klien SSMS daripada mesin host SQL Server? Saya tidak memiliki hak yang cukup di server untuk secara langsung mengakses sistem file-nya, tetapi saya memiliki hak yang cukup untuk menambah dan menghapus majelis CLR.
Zarepheth
Tidak. Yah, kebanyakan tidak. Anda dapat menentukan jalur UNC (yaitu \\ server \ path \ to \ file) dan selama akun layanan yang menjalankan mesin SQL di bawah telah membaca izin pada file, itu harus bekerja. Opsi lainnya adalah menentukan nilai biner untuk rakitan. Jika Anda sudah menggunakannya di server lain, membuat skrip alter dari sana akan memberi Anda nilai gumpalan.
Ben Thul
Ya, itulah yang saya pikirkan. :( Mungkin versi SSMS yang lebih baru akan memungkinkan pembaruan rakitan dari mesin jarak jauh. Sementara itu, saya kira saya menjatuhkan dan membuat rakitan melalui GUI SSMS - dan melakukan operasi DROP dan BUAT untuk semua fungsi dependen.
Zarepheth
Saya tidak akan menahan nafas pada yang satu itu. Sejauh harus jatuh dan membuat ulang, mengapa Anda tidak bisa menggunakan salah satu metode yang diuraikan di atas?
Ben Thul
1
"Menambah dan Mengubah rakitan memerlukan referensi sistem file." - ini tidak benar. Baik CREATE ASSEMBLYdan ALTER ASSEMBLYakan mengambil gumpalan yang mewakili majelis. Buktikan ini untuk diri Anda sendiri dengan pergi ke basis data apa pun yang dibuat pada 2008+ dan pergi ke Programmability -> Assemblies dan skrip pembuatan Microsoft.qlServer.Tipe perakitan. Varbinary raksasa itu adalah majelis . Karena ini berlaku untuk situasi Anda, sebarkan majelis Anda ke mesin virtual lokal Anda, skrip keluar, dan buat ALTER ASSEMBLYskrip.
Ben Thul
7

Untuk menambah jawaban Ben Thul, ini dapat dicapai dari jarak jauh cukup mudah melalui GUI SQL Server Management Studio .

  1. Di bawah Object Explorer untuk database Anda -> Programmability, klik kanan pada Assemblies dan pilih 'New Assembly ...'.

  2. Jelajahi DLL Anda yang diperbarui.

  3. Alih-alih mengklik 'OK' (yang akan gagal, karena majelis dengan nama yang sama sudah ada) klik 'Script' di bagian atas jendela Majelis Baru.
     
    Anda akan dimasukkan ke dalam SQL Query yang mencakup baris 'CREATE ASSEMBLY' diikuti oleh gumpalan besar yang merupakan DLL yang baru saja Anda pilih.

  4. Ubah 'BUAT' menjadi 'ALTER' dan kemudian jalankan!

Script juga membuat baris 'AUTHORISATION' untuk saya yang harus saya hapus sebelum mengeksekusi; jarak Anda mungkin berbeda.

Saya harap ini membantu orang lain tanpa akses sistem file ke server mereka.

Semoga Microsoft akan membuat ini operasi kelas satu di SSMS suatu hari nanti, tetapi ini adalah solusi yang cukup mudah sampai mereka melakukannya.

F. Shinn
sumber
1

saya menemukan petunjuk pada jawaban di Stackoverflow :

ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Ian Boyd
sumber
1
Anda berarti ALTER ASSEMBLY... ( UPDATEyang di DML, ALTERdalam DDL.)
miroxlav