Pembaruan Jan 2017 - SQL Server 2016+ / Azure SQL Database
SQL Server 2016 dan versi saat ini dari Azure SQL Database sekarang memiliki sintaks berikut untuk fungsi, prosedur, tabel, database, dll. ( DROP IF EXISTS
):
DROP FUNCTION IF EXISTS dbo.fn_myfunc;
Dan SQL Server 2016 Paket Layanan 1 menambahkan fungsionalitas yang lebih baik untuk modul (fungsi, prosedur, pemicu, tampilan) yang berarti tidak ada kehilangan izin atau dependensi ( CREATE OR ALTER
):
CREATE OR ALTER FUNCTION dbo.fn_myfunc ...
Kedua peningkatan sintaksis ini dapat menyebabkan skrip yang lebih sederhana digunakan untuk kontrol sumber, penyebaran, dll.
Tetapi, jika Anda menggunakan ...
Versi yang lebih lama
Anda perlu melakukan apa yang SQL Server lakukan ketika Anda skrip ini dari Management Studio:
IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE type = 'FN' AND name = 'fn_myfunc')
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'CREATE FUNCTION ...';
EXEC sp_executesql @sql;
END
Atau Anda bisa mengatakan:
BEGIN TRY
DROP FUNCTION dbo.fn_myfunc;
END TRY
BEGIN CATCH
PRINT 'Function did not exist.';
END CATCH
GO
CREATE FUNCTION...
Atau Anda bisa mengatakan:
DROP FUNCTION dbo.fn_myfunc;
GO
CREATE FUNCTION...
(Di sini Anda akan mendapatkan pesan kesalahan jika fungsi tersebut belum ada, tetapi skrip akan melanjutkan dari GO berikutnya, jadi apakah drop berfungsi atau tidak, fungsi tersebut masih akan (kembali) dibuat.)
Perhatikan bahwa jika Anda menjatuhkan fungsi dan membuatnya kembali, Anda akan kehilangan izin dan informasi ketergantungan yang potensial.
Kesalahannya cukup jelas. Ada beberapa cara untuk memperbaikinya.
Pisahkan skrip menjadi beberapa kumpulan di Management Studio menggunakan
GO
kata kunci semu, danDROP
/CREATE
objek. (Perhatikan bahwa kata kunci itu sendiri dapat diubah di opsi Management Studio, tapi ini adalah pengaturan de facto, jadi saya sarankan biarkan saja).Saat Anda menjalankan skrip (atau bagian skrip yang dipilih), Studio Manajemen memisahkan setiap skrip skrip antara
GO
s, dan secara berurutan mengirimkan bagian-bagian ke SQL Server sebagai kumpulan terpisah.Gunakan SQL dinamis untuk mengirim kumpulan terpisah dari dalam kumpulan lain.
Ini adalah metode yang disukai, karena dengan demikian skrip Anda tidak bergantung pada fungsi eksternal untuk mengeksekusi dengan benar. Misalnya, jika aplikasi Anda memiliki program pembaruan basis data, secara umum itu akan memuat file skrip dan kemudian menjalankannya di server target. Entah Anda harus menambahkan logika untuk memisahkan bets seperti yang dilakukan Studio Manajemen (catatan: penuh dengan bahaya), atau menulis skrip sedemikian rupa sehingga seluruh skrip dapat dieksekusi dengan sukses sebagai bets tunggal.
Seperti disebutkan dalam jawaban lain, Anda dapat melakukan tes /
CREATE
menggunakan metode ini (atau kombinasi lain dariDROP
/CREATE
, dll.). Yang saya suka lakukan adalah membuat objek rintisan jika objek tidak ada, dan kemudian gunakanALTER <object>
untuk benar-benar melakukan pembuatan atau perubahan. Pendekatan ini tidak menjatuhkan dependensi, seperti izin atau properti yang diperluas, dan tidak perlu menyalin / menempelkan logika rawan kesalahan untuk melakukanCREATE
/ALTER
dalam satu pernyataan.Berikut adalah templat yang saya gunakan untuk membuat atau mengubah fungsi skalar. Saya akan meninggalkannya sebagai latihan bagi pembaca untuk mengadaptasinya ke jenis objek lain (procs tersimpan, pemicu, dll.).
sumber
GO
benar - benar memastikan skrip akan rusak, karena itu tidakIF
akan mengarah ke mana pun.DROP
/CREATE
skenario - diedit. Terima kasih.Anda memiliki opsi untuk memeriksa apakah objek ada di
database
dan membuat jika tidak:sumber