2011-08-29 9 views
20

Estoy tratando de crear múltiples disparadores con solo cargar un script en un espacio de trabajo Oracle DB/APEX, y ejecutarlo una vez.¿Hay alguna forma de crear múltiples activadores en un script?

He aquí una breve secuencia de comandos en comparación con el que estoy tratando de usar:

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; 

He intentado poner Entra en medio de cada bloque individual, pero aún así sólo crea el primer disparo y luego me da un error para el segundo dicho:

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

Espero que sea posible hacerlo. Muchas gracias por su tiempo e interés =)

Respuesta

44

Añadir una barra inclinada en una nueva línea después de cada disparo para ejecutar el comando en el búfer:

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

¡Impresionante! Funciona al ejecutar el script en APEX (después de subirlo, por supuesto), pero actuó de manera divertida en SQL Developer ?? Oh bien, ¡¡¡Gracias !!! –

+4

@Kamron K., en SQL Developer necesitaría hacer clic en el botón "Ejecutar script (F5)" para crear todos sus activadores (no el botón principal "Ejecutar instrucción"). – Wolf

4

Coloque una barra inclinada '/' como el primer carácter en una línea en blanco entre cada declaración de activación. Este es el equivalente SQL * PLUS de 'go'.

+0

impresionante! Funciona al ejecutar el script en APEX (después de subirlo, por supuesto), pero actuó de manera divertida en SQL Developer ?? Oh bien, ¡¡¡Gracias !!! –

0

Coloque una barra inclinada

/ 

entre las dos declaraciones en una línea separada.

Oracle entonces aceptará como una nueva declaración

0

Sí podemos ejecutar múltiples procedimiento/de disparo/función en una sola secuencia de comandos con la barra diagonal/dentro del archivo sql.

, como a continuación:

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; 

/

Entonces Oracle tendrán el carácter de nueva declaración/bloque.

-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 

Cómo ejecutarlo:

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

SELECT 'Return Value' = @return_value 

go 
+0

¿No estoy seguro de cómo esta es la respuesta a la pregunta? – Carpetsmoker

Cuestiones relacionadas