2011-08-29 28 views
20

Tôi đang cố tạo nhiều trình kích hoạt chỉ bằng cách tải lên một tập lệnh vào không gian làm việc Oracle DB/APEX và chạy nó một lần.Có cách nào để tạo nhiều trình kích hoạt trong một tập lệnh không?

Dưới đây là một kịch bản ngắn gọn so với một im cố gắng sử dụng:

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; 

Tôi đã thử đặt GO ở giữa mỗi khối cá nhân, nhưng vẫn chỉ tạo ra sự kích hoạt đầu tiên sau đó mang lại cho tôi một lỗi cho câu nói thứ hai:

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

Tôi hy vọng rằng có thể thực hiện việc này. Cảm ơn bạn rất nhiều vì đã dành thời gian và sở thích =)

Trả lời

44

Thêm một dấu gạch chéo trên một dòng mới sau mỗi lần kích hoạt để thực hiện lệnh trong bộ đệm:

create trigger... 
... 
end; 
/
+0

Tuyệt vời! Hoạt động khi chạy kịch bản trong APEX (sau khi tải lên nó tất nhiên), nhưng hành động hài hước trong SQL Developer ?? Oh khỏe cảm ơn bạn!!! –

+4

@Kamron K., Trong SQL Developer, bạn sẽ cần phải bấm vào nút "Chạy tập lệnh (F5)" để tạo tất cả các trình kích hoạt của bạn (không phải nút "Chạy lệnh" chính). – Wolf

4

Đặt dấu gạch chéo '/' làm ký tự đầu tiên trên dòng trống giữa mỗi câu lệnh kích hoạt. Đây là SQL * PLUS tương đương với 'go'.

+0

Awesome! Hoạt động khi chạy kịch bản trong APEX (sau khi tải lên nó tất nhiên), nhưng hành động hài hước trong SQL Developer ?? Oh khỏe cảm ơn bạn!!! –

0

Đặt một dấu gạch chéo

/ 

giữa hai câu lệnh trên một dòng riêng biệt. sau đó

Oracle sẽ chấp nhận nó như một tuyên bố mới

0

Vâng, chúng tôi có thể thực hiện nhiều thủ tục/kích hoạt/chức năng trong kịch bản duy nhất bằng cách sử dụng dấu gạch chéo/bên trong file sql.

Giống như dưới đây:

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; 

/

Sau đó oracle sẽ xem xét nó như tuyên bố mới/block.

-4
--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 
           [email protected] + 
           @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 
             [email protected]+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 

Làm thế nào để thực hiện nó:

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

SELECT 'Return Value' = @return_value 

go 
+0

Tôi nhầm lẫn đây là câu trả lời cho câu hỏi được hỏi như thế nào? – Carpetsmoker

Các vấn đề liên quan