it-source

스크립트 하나에 여러 트리거를 생성하는 방법이 있습니까?

criticalcode 2023. 7. 15. 10:15
반응형

스크립트 하나에 여러 트리거를 생성하는 방법이 있습니까?

Oracle DB/APEX 작업 공간에 스크립트 하나만 업로드하고 한 번만 실행하여 여러 트리거를 생성하려고 합니다.

다음은 사용하려는 스크립트와 비교한 간단한 스크립트입니다.

    create or replace trigger "BI_TEC_ROLES"   
      before insert on "TEC_ROLES"               
      for each row  
    begin   
      if :NEW."ROLE_ID" is null then 
        select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual; 
      end if; 
    end; 

    create or replace trigger "BI_TEC_STATUSES"   
      before insert on "TEC_STATUSES"               
      for each row  
    begin   
      if :NEW."STATUS_ID" is null then 
        select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual; 
      end if; 
    end; 

    create or replace trigger "BI_TEC_SUBS"   
      before insert on "TEC_SUBS"               
      for each row  
    begin   
      if :NEW."SUB_ID" is null then 
        select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual; 
      end if; 
    end; 

각 개별 블록 사이에 GO를 넣으려고 시도했지만 여전히 첫 번째 트리거만 생성하고 두 번째 오류가 발생합니다.

    Error(7,1): PLS-00103: Encountered the symbol "CREATE" 

나는 이것이 가능하기를 바랍니다.시간을 내주시고 관심을 가져주셔서 정말 감사합니다=)

각 트리거 뒤에 새 줄에 슬래시를 추가하여 버퍼에서 명령을 실행합니다.

create trigger...
...
end;
/

각 트리거 문 사이의 빈 줄에 슬래시 '/'를 첫 번째 문자로 넣습니다.SQL*PLUS는 'go'에 해당합니다.

예. SQL 파일 내의 FORWARD SLASH /를 사용하여 단일 스크립트에서 여러 프로시저/트리거/함수를 실행할 수 있습니다.

아래와 같이:

create or replace trigger "BI_TEC_ROLES"   
      before insert on "TEC_ROLES"               
      for each row  
    begin   
      if :NEW."ROLE_ID" is null then 
        select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual; 
      end if; 
    end; 

/
    create or replace trigger "BI_TEC_STATUSES"   
      before insert on "TEC_STATUSES"               
      for each row  
    begin   
      if :NEW."STATUS_ID" is null then 
        select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual; 
      end if; 
    end; 

/

   create or replace trigger "BI_TEC_SUBS"   
      before insert on "TEC_SUBS"               
      for each row  
    begin   
      if :NEW."SUB_ID" is null then 
        select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual; 
      end if; 
    end; 

/

그러면 오라클은 이를 새 문/블록으로 간주합니다.

슬래시를 배치합니다.

/

두 개의 진술 사이에 다른 선이 표시됩니다.

그러면 Oracle은 이를 새 문으로 수락합니다.

--Parameter: 
--  @InclDrop bit   
--  Possible values 
--    0 - Script to drop the triggers is not generated.   
--    1 - Script to drip the triggers is generated. 

SET ansi_nulls ON 

go 

SET quoted_identifier ON 

go 


ALTER PROCEDURE [dbo].[Createscriptofalltriggers] 

@InclDrop BIT =1

AS 

DECLARE @SQL VARCHAR(8000), 
        @Text            NVARCHAR(4000), 
        @BlankSpaceAdded INT, 
        @BasePos         INT, 
        @CurrentPos      INT, 
        @TextLength      INT, 
        @LineId          INT, 
        @MaxID           INT, 
        @AddOnLen        INT, 
        @LFCR            INT, 
        @DefinedLength   INT, 
        @SyscomText      NVARCHAR(4000), 
        @Line            NVARCHAR(1000), 
        @UserName        SYSNAME, 
        @ObjID           INT, 
        @OldTrigID       INT 

SET nocount ON 
SET @DefinedLength = 1000 
SET @BlankSpaceAdded = 0 

IF @InclDrop <> 0 
  SET @InclDrop =1 

-- This Part Validated the Input parameters   
DECLARE @Triggers TABLE 
  ( 
     username SYSNAME NOT NULL, 
     trigname SYSNAME NOT NULL, 
     objid    INT NOT NULL 
  ) 
DECLARE @TrigText TABLE 
  ( 
     objid    INT NOT NULL, 
     lineid   INT NOT NULL, 
     linetext NVARCHAR(1000) NULL 
  ) 

INSERT INTO @Triggers 
            (username, 
             trigname, 
             objid) 
SELECT DISTINCT A.NAME, 
                B.NAME, 
                B.id 
FROM   dbo.sysusers A, 
       dbo.sysobjects B, 
       dbo.syscomments C 
WHERE  A.uid = B.uid 
       AND B.type = 'Tr' 
       AND B.id = C.id 
       AND C.encrypted = 0 

IF EXISTS(SELECT C.* 
          FROM   syscomments C, 
                 sysobjects O 
          WHERE  O.id = C.id 
                 AND O.type = 'Tr' 
                 AND C.encrypted = 1) 
  BEGIN 
      PRINT '/*' 

      PRINT 'The following encrypted triggers were found' 

      PRINT 'The procedure could not write the script for it' 

      SELECT DISTINCT A.NAME, 
                      B.NAME, 
                      B.id 
      FROM   dbo.sysusers A, 
             dbo.sysobjects B, 
             dbo.syscomments C 
      WHERE  A.uid = B.uid 
             AND B.type = 'Tr' 
             AND B.id = C.id 
             AND C.encrypted = 1 

      PRINT '*/' 
  END 

DECLARE ms_crs_syscom CURSOR local forward_only FOR 
  SELECT T.objid, 
         C.text 
  FROM   @Triggers T, 
         dbo.syscomments C 
  WHERE  T.objid = C.id 
  ORDER  BY T.objid, 
            C.colid 
  FOR READ only 

SELECT @LFCR = 2 

SELECT @LineId = 1 

OPEN ms_crs_syscom 

SET @OldTrigID = -1 

FETCH next FROM ms_crs_syscom INTO @ObjID, @SyscomText 

WHILE @@fetch_status = 0 
  BEGIN 
      SELECT @BasePos = 1 

      SELECT @CurrentPos = 1 

      SELECT @TextLength = Len(@SyscomText) 

      IF @ObjID <> @OldTrigID 
        BEGIN 
            SET @LineID = 1 
            SET @OldTrigID = @ObjID 
        END 

      WHILE @CurrentPos != 0 
        BEGIN 
            --Looking for end of line followed by carriage return         
            SELECT @CurrentPos = Charindex(Char(13) + Char(10), @SyscomText, 
                                 @BasePos) 

            --If carriage return found         
            IF @CurrentPos != 0 
              BEGIN 

                  WHILE ( Isnull(Len(@Line), 0) + @BlankSpaceAdded 
                          + @CurrentPos - @BasePos + @LFCR ) > 
                        @DefinedLength 
                    BEGIN 
                        SELECT @AddOnLen = @DefinedLength - ( 
                                           Isnull(Len(@Line), 
                                           0 
                                           ) + 
                                           @BlankSpaceAdded ) 

                        INSERT @TrigText 
                        VALUES ( @ObjID, 
                                 @LineId, 
                                 Isnull(@Line, N'') 
                                 + Isnull(Substring(@SyscomText, @BasePos, 
                                 @AddOnLen), 
                                 N'')) 

                        SELECT @Line = NULL, 
                               @LineId = @LineId + 1, 
                               @BasePos = @BasePos + @AddOnLen, 
                               @BlankSpaceAdded = 0 
                    END 

                  SELECT @Line = Isnull(@Line, N'') 
                                 + Isnull(Substring(@SyscomText, @BasePos, 
                                 @CurrentPos 
                                 -@BasePos + 
                                 @LFCR), 
                                        N'') 

                  SELECT @BasePos = @CurrentPos + 2 

                  INSERT @TrigText 
                  VALUES( @ObjID, 
                          @LineId, 
                          @Line ) 

                  SELECT @LineId = @LineId + 1 

                  SELECT @Line = NULL 
              END 
            ELSE 
              --else carriage return not found         
              BEGIN 
                  IF @BasePos <= @TextLength 
                    BEGIN 
                        /*If new value for @Lines length will be > then the         
                        **defined length         
                        */ 
                        WHILE ( Isnull(Len(@Line), 0) + @BlankSpaceAdded 
                                + @TextLength - @BasePos + 1 ) > 
                              @DefinedLength 
                          BEGIN 
                              SELECT @AddOnLen = @DefinedLength - ( 
                                                 Isnull(Len(@Line), 
                                                 0 
                                                 ) + 
                                                 @BlankSpaceAdded ) 

                              INSERT @TrigText 
                              VALUES ( @ObjID, 
                                       @LineId, 
                                       Isnull(@Line, N'') 
                                       + Isnull(Substring(@SyscomText, 
                                       @BasePos, 
                                       @AddOnLen), 
                                       N'')) 

                              SELECT @Line = NULL, 
                                     @LineId = @LineId + 1, 
                                     @BasePos = @BasePos + @AddOnLen, 
                                     @BlankSpaceAdded = 0 
                          END 

                        SELECT @Line = Isnull(@Line, N'') 
                                       + Isnull(Substring(@SyscomText, 
                                       @BasePos, 
                                       @TextLength 
                                       -@BasePos+1 
                                       ), N'') 

                        IF Len(@Line) < @DefinedLength 
                           AND Charindex(' ', @SyscomText, @TextLength + 1) 
                               > 0 
                          BEGIN 
                              SELECT @Line = @Line + ' ', 
                                     @BlankSpaceAdded = 1 
                          END 
                    END 
              END 
        END 

      FETCH next FROM ms_crs_syscom INTO @ObjID, @SyscomText 
  END 

IF @Line IS NOT NULL 
  INSERT @TrigText 
  VALUES( @ObjID, 
          @LineId, 
          @Line ) 

CLOSE ms_crs_syscom 

PRINT '-- You should run this result under dbo if your triggers belong to multiple users' 

PRINT '' 

IF @InclDrop = 1 
  BEGIN 
      PRINT '-- Dropping the Triggers' 

      PRINT '' 

      SELECT 'If exists(Select * from sysObjects where id =Object_ID(''[' 
             + username + '].[' + trigname 
             + ']'') and ObjectProperty(Object_ID(''[' 
             + username + '].[' + trigname + ']''), ''ISTRIGGER'')=1)   Drop Trigger [' 
             + username + '].[' + trigname + '] ' + Char(13) 
             + Char(10) + 'GO' + Char(13) + Char(10) + Char(13) 
             + Char(10) 
      FROM   @Triggers 
  END 

PRINT '----------------------------------------------' 

PRINT '-- Creation of Triggers' 

PRINT '' 

PRINT '' 

DECLARE ms_users CURSOR local forward_only FOR 
  SELECT T.username, 
         T.objid, 
         Max(D.lineid) 
  FROM   @Triggers T, 
         @TrigText D 
  WHERE  T.objid = D.objid 
  GROUP  BY T.username, 
            T.objid 
  FOR READ only 

OPEN ms_users 

FETCH next FROM ms_users INTO @UserName, @ObjID, @MaxID 

WHILE @@fetch_status = 0 
  BEGIN 
      PRINT 'SetUser N''' + @UserName + '''' + Char(13) 
            + Char(10) 

      SELECT '-- Text of the Trigger'= CASE lineid 
                                         WHEN 1 THEN 'GO' + Char(13) + Char( 
                                                     10) 
                                                     + 
                                                     linetext 
                                         WHEN @MaxID THEN linetext + 'GO' 
                                         ELSE linetext 
                                       END 
      FROM   @TrigText 
      WHERE  objid = @ObjID 
      ORDER  BY lineid 

      PRINT 'Setuser' 

      FETCH next FROM ms_users INTO @UserName, @ObjID, @MaxID 
  END 

CLOSE ms_users 

PRINT 'GO' 

PRINT '------End ------' 

DEALLOCATE ms_crs_syscom 

DEALLOCATE ms_users 

SET nocount ON 

DECLARE @return_value INT 

실행 방법:

EXEC @return_value = [dbo].[Createscriptofalltriggers] 
  @InclDrop = 1 

SELECT 'Return Value' = @return_value 

go 

언급URL : https://stackoverflow.com/questions/7233210/is-there-a-way-to-create-multiple-triggers-in-one-script

반응형