저장 프로 시저가 이미 있는지 확인하는 방법


130

저장 프로 시저가 존재하거나 존재하지 않는 경우 작동하는 배포 스크립트를 작성해야합니다. 즉, 존재하는 경우 변경해야하며, 그렇지 않으면 작성해야합니다.

SQL에서 어떻게 할 수 있습니까?

SQL Server 2005를 사용하고 있습니다


답변:


160

프로 시저를 삭제하고 작성하면 보안 설정이 해제됩니다. 이로 인해 DBA가 성가 시거나 애플리케이션이 완전히 중단 될 수 있습니다.

내가하는 일은 아직 간단한 저장 프로 시저를 만들지 않는 것입니다. 그런 다음 저장 프로 시저를 원하는대로 변경할 수 있습니다.

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

이런 식으로 보안 설정, 주석 및 기타 메타 데이터는 배포 후에도 유지됩니다.


2
최소한 삭제하면 권한을 다시 추가해야합니다. 이 SQL을 실행하면 sproc에 올바른 권한이 있는지 여부를 알 수 없으므로 생성했는지 또는 변경했는지 알 수 없습니다.
Liazy

@Liazy 간단한 해결책 if object_id('YourSp') is null BEGIN ... END은 저장 프로 시저를 만든 후 적절한 권한을 추가 하기 위해 코드 를 추가하는 것입니다.
saluce

4
다른 답변은 저장 프로 시저의 객체 ID 만 가져 오기 때문에 조금 더 완전하다고 생각하십시오. 다른 유형에 대해 동일한 이름을 갖는 것은 일반적이지 않지만 일어날 수 있습니다.
workabyte

149

가장 깨끗한 방법은 존재 여부를 테스트하고 존재하는 경우 삭제 한 다음 다시 작성하는 것입니다. IF 문 안에 "create proc"문을 포함시킬 수 없습니다. 이것은 잘해야합니다 :

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

CREATE PROC MySproc
AS
BEGIN
    ...
END

1
작동하지만 저장 프로 시저에 적용된 모든 보안 변경 사항이 제거됩니다.
Andomar

18
보안 변경도 스크립트의 일부 여야합니다. 그렇게하면 제대로 문서화됩니다. 이것이 올바른 접근법입니다.
엔더 Wiggin

@EnderWiggin 디자인 타임에 보안 구현을 모르는 경우를 제외하고 ... 개발자가 실행 권한이 필요한 사용자를 개발자가 모르는 경우 어떻게해야합니까?
Adriaan Davel

2
@AdriaanDavel l DBA가 무엇인지, DBA가 개발자와 대화하게하는 것을 관리라고합니다. 개발자와 DBA가 함께 작업 할 수 없으면 회사에 문제가있는 것입니다. 또한, 제대로 구현 된 시스템은 데이터베이스를 만지기 위해 사용자 권한에 의존하지 않으며, 이는 서비스 계정의 목적이며, 서비스 수준 보안은 데이터베이스 전체에 적용되어야합니다. 이런 식으로 DBA는 보안을 조정하는 데 시간과 돈을 소비 할 필요가 없습니다. 개별 sprocs.
Shaun Wilson

2
상용 제품에 속하는 sprocs를 삭제 / 재 작성하는 개발자는 없습니다. 그것에 대해 생각해 보니 DBA도 그렇게하지 않을 것입니다. 그래도 "DBA가 상용 제품에 대한 sproc 사후 배치에 대한 보안을 조정해야하는 경우"에 대해 알고 있습니다. 적절하게 구현 된 시스템은 사용자 권한에 의존하지 않으며 서비스 수준 보안은 데이터베이스 전체에 적용되어야합니다. 데모 / 스크래치 시스템에 설치 한 다음 스키마를 비교하여 업그레이드가 안전한지 확인하는 DBA와 함께 작업했습니다. 이것이 IMO가 고용 한 작업입니다.
Shaun Wilson

31

저장 프로 시저 만 처리하는 경우 가장 쉬운 방법은 proc을 삭제 한 다음 다시 만드는 것입니다. 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

에서 SQL Server 2016 CTP3당신은 새 사용할 수 있습니다 다이 문 대신 큰 IF래퍼를

통사론:

삭제 {PROC | 절차} [존재하는 경우] {[schema_name. ] 절차} [, ... n]

질문:

DROP PROCEDURE IF EXISTS usp_name

더 많은 정보는 여기에


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 이름은 어디에 있습니까


4

이미 말한 것 외에도 다른 접근 방식을 추가하고 차등 스크립트 배포 전략의 사용을 옹호하고 싶습니다. 항상 현재 상태를 확인하고 해당 상태를 기반으로 작동하는 상태 저장 스크립트를 만드는 대신, 잘 알려진 버전에서 업그레이드하는 일련의 상태 비 저장 스크립트를 통해 배포하십시오 . 필자는이 전략을 사용했으며 이제 배포 스크립트가 모두 'IF'가 아니므로 시간이 많이 걸립니다.


흥미 롭습니다! 이 답변을 게시 한 후 5 년 동안 데이터베이스 버전 관리 방법이 추가로 개발 되었습니까?
토마스 엘 할러데이

4

다음과 같이 쿼리를 작성할 수 있습니다.

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

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

위의 구문을보다 구체적으로 설명하면 :
OBJECT_ID 는 데이터베이스 내의 개체에 대한 고유 한 ID 번호이며 SQL Server에서 내부적으로 사용됩니다. 우리가 전달되기 때문에 ProcedureName는 당신이 다음 유형의 객체 P 는 호출 된 객체 찾아야하는 SQL 서버를 알려줍니다 ProcedureName 타입이다 절차 즉, P를

이 쿼리는 프로 시저를 찾은 후 사용 가능한 경우이를 삭제하고 새 프로 시저를 작성합니다.

OBJECT_ID 및 오브젝트 유형에 대한 자세한 정보는 다음을 방문하십시오. SYS.Objects



0

고객이 유효성 검사를 확장 할 수있는 저장 프로 시저가 있습니다. 존재하는 경우 변경하고 싶지 않습니다. 만약 그것을 만들고 싶지 않다면 내가 찾은 가장 좋은 방법입니다.

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
다운 투표를 제공하지는 않았지만 추측에 따르면이 솔루션은 저장 프로 시저 본문 내에서 따옴표 문자를 이스케이프 처리하여 새로운 합병증을 유발하기 때문에 다운 투표되었다고 말할 수 있습니다.
donperk

0

아래 코드는 저장 프로 시저가 이미 존재하는지 여부를 확인합니다.

존재하는 경우 변경되고 존재하지 않는 경우 새 저장 프로 시저를 만듭니다.

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

더 나은 옵션은 Red-Gate SQL Compare 또는 SQL Examiner와 같은 도구를 사용하여 차이점을 자동으로 비교하고 마이그레이션 스크립트를 생성하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.