programing

저장 프로시저가 없는 경우 생성

elecom 2023. 10. 5. 21:11
반응형

저장 프로시저가 없는 경우 생성

저장된 프로시저 목록이 있는지 확인하고 싶습니다.이 모든 것을 하나씩 하나의 대본으로 했으면 좋겠습니다.지금까지는 다음과 같은 형식을 가지고 있습니다.

USE [myDatabase]
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'sp_1')
BEGIN
CREATE PROCEDURE sp_1
AS
.................
END
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'sp_2')
BEGIN
CREATE PROCEDURE sp_2
AS
.................
END
GO

등등.그러나 다음 오류가 발생합니다.

'Procedure' 키워드 근처의 구문이 잘못되었습니다.

제가 하고 있는 일이 왜 제대로 작동하지 않는 겁니까?

CREATE PROCEDURE배치의 첫 번째 문이어야 합니다.저는 보통 다음과 같은 일을 합니다.

IF EXISTS (
        SELECT type_desc, type
        FROM sys.procedures WITH(NOLOCK)
        WHERE NAME = 'myProc'
            AND type = 'P'
      )
     DROP PROCEDURE dbo.myProc
GO

CREATE PROC dbo.myProc

AS
....

    GO
    GRANT EXECUTE ON dbo.myProc TO MyUser 

(프로크를 다시 작성하면 손실되므로 승인문을 잊지 마십시오.)

저장 프로시저를 배포할 때 고려해야 할 다른 한 가지 사항은 드롭이 성공하고 생성이 실패할 수 있다는 것입니다.문제가 발생할 경우 항상 롤백을 통해 SQL 스크립트를 작성합니다.마지막에 커밋/롤백 코드를 실수로 삭제하지 않도록 해야 합니다. 그렇지 않으면 DBA가 기관을 두드릴 수 있습니다. :)

BEGIN TRAN 
IF EXISTS (
       SELECT type_desc, type
       FROM sys.procedures WITH(NOLOCK)
       WHERE NAME = 'myProc'
           AND type = 'P'
     )
DROP PROCEDURE myProc GO
CREATE PROCEDURE myProc
   
AS
   --proc logic here

GO
-- BEGIN DO NOT REMOVE THIS CODE (it commits or rolls back the stored procedure drop) 
    IF EXISTS(
               SELECT 1
               FROM sys.procedures WITH(NOLOCK)
               WHERE NAME = 'myProc'
                   AND type = 'P'
             )
        COMMIT TRAN
        ELSE
        ROLLBACK TRAN
-- END DO NOT REMOVE THIS CODE

제가 최근에 많이 사용하는 관용구는 다음과 같습니다.

if exists (select 1 from sys.objects where object_id = object_id('dbo.yourProc'))
   set noexec on
go
create procedure dbo.yourProc as
begin
   select 1 as [not yet implemented]
end
go
set noexec off
alter procedure dbo.yourProc as
begin
   /*body of procedure here*/
end

기본적으로 절차가 존재하지 않는 경우 스터브를 생성한 다음 스터브(단지 생성된 경우) 또는 기존 절차를 변경하는 것입니다.좋은 점은 모든 권한을 삭제하는 기존 절차를 삭제하지 않는다는 것입니다.또한 애플리케이션이 존재하지 않는 짧은 순간에 애플리케이션을 원하는 경우에도 문제를 일으킬 수 있습니다.

- [Edit 2018-02-09] - SQL 2016 SP1 에서,create procedure그리고.drop procedure이런 일에 도움이 되는 통사적인 설탕이 좀 있어요.구체적으로, 이제 다음을 수행할 수 있습니다.

create or alter dbo.yourProc as
go

drop procedure if exists dbo.yourProc;

둘 다 의도한 문에 idempotency를 제공합니다(즉, 여러 번 실행하면 원하는 상태가 됨).지금은 이렇게 해야 합니다(사용자가 SQL Server를 지원하는 버전에 있다고 가정).

수용된 답변이 있다는 것은 알고 있지만, 그 답변은 원래 질문이 무엇을 묻는지, 즉 만약 그것이 존재하지 않는다면 절차를 작성하라는 것을 정확하게 다루지는 않습니다.다음은 항상 작동하며 sql 인증을 사용할 경우 문제가 될 수 있는 드롭 절차가 필요하지 않다는 장점이 있습니다.

USE [MyDataBase]
GO

IF OBJECT_ID('mySchema.myProc') IS NULL
EXEC('CREATE PROCEDURE mySchema.myProc AS SET NOCOUNT ON;')
GO

ALTER PROCEDURE mySchema.myProc
    @DeclaredParmsGoHere    DataType

AS 
   BEGIN
       DECLARE @AnyVariablesINeed    Their DataType
   SELECT myColumn FROM myTable WHERE myIndex = @IndexParm

2020년 9월 업데이트됨

생성 또는 변경 문(SQL Server 2016 SP1에서 추가됨)을 사용할 수 있습니다.

CREATE OR ALTER문장은 정상처럼 작용합니다.CREATE데이터베이스 개체가 존재하지 않고 정상처럼 작동하는 경우 데이터베이스 개체를 생성하여 문ALTER데이터베이스 개체가 이미 존재하는 경우 문.

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[spGetRailItems]') AND type in (N'P', N'PC'))
BEGIN 
execute ('
CREATE PROCEDURE [dbo].[spGetRailItems]  
AS  
BEGIN  

Declare @isLiftedBagsEnable bit=1;  
select @isLiftedBagsEnable=cast(DataValu as bit) from setups where scope =''Rail Setting'' and dataName = ''isLiftedBagsEnable'';

IF @isLiftedBagsEnable=1
BEGIN
    IF EXISTS (SELECT * FROM ITEMCONFIG)
    BEGIN
        SELECT [Item],[Desc] FROM ProcData WHERE Item IN (SELECT Item FROM ItemConfig) ORDER BY [Desc]
    END
    ELSE
    BEGIN
        SELECT [Item],[Desc] FROM ProcData ORDER BY [Desc]
    END
END
ELSE
BEGIN
    SELECT [Item],[Desc] FROM ProcData ORDER BY [Desc]
END

END

')
END

exec spGetRailItems;

SQL Server 2016을 사용하는 경우에는 프로세스가 존재하는지 확인한 후 삭제하고 다시 만드는 짧은 버전이 있습니다.

USE [DATABASENAME]
GO
DROP PROCEDURE IF EXISTS <proc name>
GO
CREATE PROCEDURE <proc name>
AS
-- your script here
END
GO
GRANT EXECUTE ON <proc name> TO <username>

출처 : https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/

USE [myDatabase]
GO

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'sp_1')
BEGIN
  DROP PROCEDURE sp_1
END
GO   --<-- Add a Batch Separator here



CREATE PROCEDURE sp_1
AS
.................
END
GO

SQL Server 2017 이상 버전에서는 "IF EXISTARS"를 사용하여 프로시저를 삭제하거나 "CREATE OR ALTER PROCEDURE"를 사용할 수 있습니다.

USE [myDatabase]
GO

DROP PROCEDURE IF EXISTS sp_1;
GO   --<-- Add a Batch Separator here



CREATE OR ALTER PROCEDURE sp_1
AS
BEGIN
  .................
END
GO

당신은 그냥 무시해도 됩니다."DROP IF EXISTS"명령하고 그냥 사용"CREATE OR ALTER"

사용하는것을 좋아합니다ALTER권한을 잃지 않고 구문 오류가 있는 경우 이전 버전이 여전히 존재합니다.

BEGIN TRY
    --if procedure does not exist, create a simple version that the ALTER will replace.  if it does exist, the BEGIN CATCH will eliminate any error message or batch stoppage
    EXEC ('CREATE PROCEDURE AAAAAAAA AS DECLARE @A varchar(100); SET @A=ISNULL(OBJECT_NAME(@@PROCID), ''unknown'')+'' was not created!''; RAISERROR(@A,16,1);return 9999')
END TRY BEGIN CATCH END CATCH
GO

ALTER PROCEDURE AAAAAAAA 
(
     @ParamsHere varchar(10)
)
AS
PRINT 'HERE IN '+(OBJECT_NAME(@@PROCID))
GO

다음을 실행할 수 있습니다.

DROP PROCEDURE IF EXISTS name_of_procedure;
CREATE PROCEDURE name_of_procedure(....)

언급URL : https://stackoverflow.com/questions/22950165/creating-a-stored-procedure-if-it-does-not-already-exist

반응형