Bir saklı yordamın zaten mevcut olup olmadığı nasıl tespit edilir


Yanıtlar:


160

Prosedürü DÜŞÜR ve OLUŞTURURsanız, güvenlik ayarlarını kaybedersiniz. Bu, DBA'nızı rahatsız edebilir veya uygulamanızı tamamen bozabilir.

Yaptığım şey, henüz yoksa önemsiz bir saklı yordam oluşturmaktır. Bundan sonra, saklı yordamı beğeninize göre DEĞİŞTİRebilirsiniz.

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

Bu şekilde, güvenlik ayarları, yorumlar ve diğer meta detaylar dağıtımdan kurtulacaktır.


2
En azından onu bırakırsanız, izinleri yeniden eklemeniz gerektiğini bilirsiniz. Bu sql'yi çalıştırsaydınız, sproc'un doğru izinlere sahip olup olmadığını bilemezsiniz, çünkü onu siz mi yarattığınızı veya değiştirdiğinizi bilemezsiniz.
Liazy

@Liazy basit çözüm if object_id('YourSp') is null BEGIN ... END, depolanan yordamı oluşturduktan sonra uygun izinleri eklemek için kod eklemektir.
saluce

4
diğer cevabın sadece saklı yordamlar için nesne kimliğini çektiğinden biraz daha eksiksiz olduğunu düşünün. farklı türler için aynı ada sahip olmak yaygın değildir, ancak olabilir
workabyte

149

En temiz yol, varlığını test etmek, varsa onu bırakmak ve sonra yeniden yaratmaktır. Bir IF ifadesinin içine "create proc" ifadesi yerleştiremezsiniz. Bu güzelce yapmalı:

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

CREATE PROC MySproc
AS
BEGIN
    ...
END

1
Bu işe yarayacaktır, ancak saklı yordama uygulanan tüm güvenlik değişikliklerini kaldırır.
Andomar

18
Güvenlik değişiklikleri de komut dosyalarının parçası olmalıdır. Bu şekilde, uygun şekilde belgelenecektir. Bu doğru yaklaşımdır.
Ender Wiggin

@EnderWiggin Tasarım zamanında güvenlik uygulamasının bilinmemesi dışında ... Ya geliştirici hangi kullanıcıların yürütme haklarına ihtiyaç duyduğunu bilmiyorsa?
Adriaan Davel

2
@AdriaanDavel l, DBA'lar bunun için var ve DBA'ların geliştiricilerle konuşmasına yönetim denir. Geliştiriciler ve DBA'lar birlikte çalışamazsa, şirkette bir sorun vardır. Ayrıca, düzgün bir şekilde uygulanan sistemler, bir veritabanına dokunmak için kullanıcı ayrıcalığına güvenmez, bu hizmet hesapları içindir ve hizmet düzeyi güvenliği, veritabanı genelinde uygulanabilir olmalıdır, bu şekilde DBA'ların güvenliği ayarlamak için zaman ve para harcaması gerekmez. bireysel dişliler.
Shaun Wilson

2
Geliştiricilerin ticari bir ürüne ait olan dişleri bırakıp yeniden yaratmasına izin vermezdim. Bir düşünün, DBA'ları da bunu yapmazdım. Neye ulaştığınızı anlıyorum, yani "DBA'ların bir ticari ürün için bir sproc dağıtım sonrası güvenliği ayarlaması gerekiyorsa ne olur". Düzgün uygulanan sistemlerin kullanıcı ayrıcalıklarına dayanmadığını ve hizmet düzeyinde güvenliğin veritabanı genelinde uygulanması gerektiğini tekrar edeceğim. Bir demo / kazı kazan sistemine yüklenecek DBA'larla çalıştım ve ardından bir yükseltmenin güvenli olduğundan emin olmak için bir şema karşılaştırması yaptım, IMO bu işe alındıkları şey.
Shaun Wilson

31

Yalnızca saklı yordamlarla uğraşıyorsanız, yapılacak en kolay şey muhtemelen proc'u bırakıp yeniden oluşturmaktır. SQL Server'daki Komut Dosyaları Oluştur sihirbazını kullanarak bunu yapmak için tüm kodu oluşturabilirsiniz.

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

Sizden büyük sarmalayıcılar yerine SQL Server 2016 CTP3yeni DIE ifadeleri kullanabilirsinizIF

Sözdizimi:

DROP {PROC | PROSEDÜR} [VARSA] {[şema_adı. ] prosedür} [, ... n]

Sorgu:

DROP PROCEDURE IF EXISTS usp_name

Daha fazla bilgi burada


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

xxxproc adı nerede


4

Daha önce söylenenlere ek olarak, farklı bir yaklaşım eklemeyi ve farklı komut dosyası dağıtım stratejisinin kullanımını savunmayı da seviyorum. Her zaman mevcut durumu kontrol eden ve bu duruma göre hareket eden durum bilgisi olan bir komut dosyası yapmak yerine, iyi bilinen sürümlerden yükseltme yapan bir dizi durumsuz komut dosyası aracılığıyla dağıtın . Bu stratejiyi kullandım ve dağıtım komut dosyalarımın tümü 'EĞER' ücretsiz olduğundan büyük zaman kazandırıyor.


İlginç! Bu yanıtı gönderdikten sonraki beş yıl içinde, veritabanı sürümü kontrol yöntemlerinde başka gelişmeler oldu mu?
Thomas L Holaday

4

Aşağıdaki gibi bir sorgu yazabilirsiniz:

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

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

Yukarıdaki sözdizimi hakkında daha spesifik olmak gerekirse:
OBJECT_ID , veritabanı içindeki bir nesne için benzersiz bir kimlik numarasıdır ve bu, SQL Server tarafından dahili olarak kullanılır. Biz geçiyoruz yana ProcedureName sizin takiben tip nesne P aradığınız nesneyi bulmak gerektiğini SQL Server söyler ProcedureName tipi olan prosedür yani P

Bu sorgu prosedürü bulacak ve eğer mevcutsa onu bırakıp yenisini oluşturacaktır.

OBJECT_ID ve Nesne türleri hakkında ayrıntılı bilgi için lütfen şu adresi ziyaret edin: SYS.Objects



0

Müşterinin doğrulamayı uzatmasına izin veren depolanmış bir işlemim var, varsa, değiştirmek istemiyorum, oluşturmak istemiyorsam bulduğum en iyi yol:

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
Olumsuz oy vermedim, ancak tahminimce aşağı oy verildiğini söyleyebilirim çünkü bu çözüm, saklı yordamın gövdesi içinde kaçan alıntı karakterleriyle yeni komplikasyonlar ortaya çıkarıyor.
donperk

0

Aşağıdaki kod, saklı yordamın zaten var olup olmadığını kontrol edecektir.

Varsa değişecek, yoksa sizin için yeni bir saklı yordam oluşturacaktır:

//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

Farklılıkları otomatik olarak karşılaştırmak ve bir geçiş betiği oluşturmak için Red-Gate SQL Compare veya SQL Examiner gibi bir araç kullanmak daha iyi bir seçenek olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.