Cara mendeteksi jika prosedur tersimpan sudah ada


Jawaban:


160

Jika Anda MENGHENTIKAN dan MENCIPTAKAN prosedur, Anda akan kehilangan pengaturan keamanan. Ini bisa mengganggu DBA Anda atau menghancurkan aplikasi Anda sama sekali.

Apa yang saya lakukan adalah membuat prosedur tersimpan sepele jika belum ada. Setelah itu, Anda dapat mengubah prosedur tersimpan sesuai dengan keinginan Anda.

IF object_id('YourSp') IS NULL
    EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...

Dengan cara ini, pengaturan keamanan, komentar dan meta deta lainnya akan selamat dari penyebaran.


2
Setidaknya jika Anda menjatuhkannya, Anda tahu Anda harus menambahkan kembali izin. Jika Anda menjalankan sql ini, Anda tidak akan tahu apakah sproc memiliki izin yang benar atau tidak karena Anda tidak akan tahu apakah Anda telah membuatnya atau mengubahnya.
Liazy

@ Liazy solusi sederhana untuk menambahkan kode di if object_id('YourSp') is null BEGIN ... ENDuntuk menambahkan izin yang tepat setelah membuat prosedur tersimpan.
bernilai

4
pikir jawaban lain sedikit lebih lengkap karena hanya menarik id objek untuk prosedur tersimpan. tidak umum untuk memiliki nama yang sama untuk berbagai jenis tetapi itu bisa terjadi
workabyte

149

Cara terbersih adalah dengan menguji keberadaannya, jatuhkan jika ada, lalu buat ulang. Anda tidak dapat menanamkan pernyataan "buat proc" di dalam pernyataan IF. Ini harus dilakukan dengan baik:

IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO

CREATE PROC MySproc
AS
BEGIN
    ...
END

1
Ini akan berhasil, tetapi menghapus semua perubahan keamanan yang diterapkan pada prosedur tersimpan.
Andomar

18
Perubahan keamanan harus menjadi bagian dari skrip juga. Dengan begitu, itu akan didokumentasikan dengan baik. Ini adalah pendekatan yang tepat.
Ender Wiggin

@EnderWiggin Kecuali jika implementasi keamanan tidak tahu pada waktu desain ... Bagaimana jika pengembang tidak tahu pengguna mana yang membutuhkan hak eksekusi?
Adriaan Davel

2
@AdriaanDavel l untuk itulah DBA, dan membuat DBA untuk berbicara dengan pengembang disebut manajemen. Jika pengembang dan DBA tidak dapat bekerja bersama, ada masalah dengan perusahaan. Selain itu, sistem yang diimplementasikan dengan benar tidak bergantung pada hak istimewa pengguna untuk menyentuh database, itulah gunanya akun layanan, dan keamanan tingkat layanan harus dapat diterapkan di seluruh basis data, dengan cara ini DBA tidak perlu menghabiskan waktu dan uang untuk mengutak-atik keamanan pada sprocs individu.
Shaun Wilson

2
Saya tidak akan membiarkan pengembang menjatuhkan / membuat ulang sprocs milik produk komersial. Kalau dipikir-pikir, aku juga tidak akan meminta DBA. Saya melihat apa yang Anda maksud, yaitu, "bagaimana jika DBA perlu mengutak-atik keamanan pada sproc pasca-penempatan untuk produk komersial". Saya akan menegaskan kembali bahwa sistem yang diimplementasikan dengan benar tidak bergantung pada hak pengguna dan bahwa keamanan tingkat layanan harus diterapkan di seluruh basis data. Saya telah bekerja dengan DBA yang akan menginstal ke sistem demo / awal dan kemudian melakukan skema membandingkan untuk memastikan upgrade aman, IMO ini adalah apa yang mereka disewa untuk dilakukan.
Shaun Wilson

31

Jika Anda hanya berurusan dengan prosedur tersimpan, hal yang paling mudah untuk dilakukan adalah mungkin menjatuhkan proc, lalu membuatnya kembali. Anda bisa menghasilkan semua kode untuk melakukan ini menggunakan panduan Menghasilkan Script di SQL Server.

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]

CREATE PROCEDURE YourSproc...

20

Dari SQL Server 2016 CTP3Anda dapat menggunakan pernyataan DIE baru, bukan IFpembungkus besar

Sintaksis:

DROP {PROC | PROSEDUR} [JIKA ADA] {[schema_name. ] prosedur} [, ... n]

Pertanyaan:

DROP PROCEDURE IF EXISTS usp_name

Info lebih lanjut di sini


11
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx

dimana xxxnama proc


4

Selain apa yang telah dikatakan, saya juga ingin menambahkan pendekatan yang berbeda dan menganjurkan penggunaan strategi penyebaran skrip diferensial. Alih-alih membuat skrip stateful yang selalu memeriksa keadaan saat ini dan bertindak berdasarkan kondisi itu, gunakan melalui serangkaian skrip stateless yang meningkatkan versi dari versi terkenal . Saya telah menggunakan strategi ini dan itu menghasilkan banyak waktu karena skrip penerapan saya sekarang semuanya 'JIKA' gratis.


Menarik! Dalam lima tahun sejak Anda memposting jawaban ini, apakah sudah ada perkembangan lebih lanjut dalam metode kontrol versi database Anda?
Thomas L Holaday

4

Anda dapat menulis kueri sebagai berikut:

IF OBJECT_ID('ProcedureName','P') IS NOT NULL
    DROP PROC ProcedureName
GO

CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....

Untuk lebih spesifik pada sintaks di atas:
OBJECT_ID adalah nomor id unik untuk objek dalam database, ini digunakan secara internal oleh SQL Server. Karena kita melewati ProcedureName diikuti oleh Anda objek tipe P yang memberitahu SQL Server bahwa Anda harus menemukan objek yang disebut ProcedureName yang merupakan tipe prosedur yaitu, P

Kueri ini akan menemukan prosedur dan jika tersedia itu akan menjatuhkannya dan membuat yang baru.

Untuk informasi terperinci tentang OBJECT_ID dan jenis Objek, silakan kunjungi: SYS.Objects



0

Saya memiliki proc tersimpan yang memungkinkan pelanggan untuk memperpanjang validasi, jika ada, saya tidak ingin mengubahnya, jika tidak saya ingin membuatnya, cara terbaik yang saya temukan:

IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
    EXEC ('CREATE PROCEDURE ValidateRequestPost 
    @RequestNo VARCHAR(30),
    @ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
    SELECT @ErrorStates = @ErrorStates
END')
END

2
Saya tidak memberikan down-vote, tetapi, pada tebakan, saya akan mengatakan bahwa itu down-vote karena solusi ini memperkenalkan komplikasi baru dengan lolosnya karakter kutipan dalam tubuh prosedur tersimpan.
donperk

0

Kode di bawah ini akan memeriksa apakah prosedur yang tersimpan sudah ada atau belum.

Jika ada itu akan berubah, jika tidak ada itu akan membuat prosedur tersimpan baru untuk Anda:

//syntax for Create and Alter Proc 
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test'; 
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test'; 
//Actual Procedure 
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END'; 
//Checking For Sp
IF EXISTS (SELECT * 
           FROM   sysobjects 
           WHERE  id = Object_id('[dbo].[sp_cp_test]') 
                  AND Objectproperty(id, 'IsProcedure') = 1 
                  AND xtype = 'p' 
                  AND NAME = 'sp_cp_test') 
  BEGIN 
      SET @Proc=@Alter + @Proc 

      EXEC (@proc) 
  END 
ELSE 
  BEGIN 
      SET @Proc=@Create + @Proc 

      EXEC (@proc) 
  END 

go 

0

Pilihan yang lebih baik mungkin menggunakan alat seperti Red-Gate SQL Compare atau SQL Examiner untuk secara otomatis membandingkan perbedaan dan menghasilkan skrip migrasi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.