반응형
스크립트 하나에 여러 트리거를 생성하는 방법이 있습니까?
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
반응형
'it-source' 카테고리의 다른 글
Firebase 인증 vs AWS Cognito (0) | 2023.07.15 |
---|---|
iOS 로직 테스트와 함께 CocoaPod를 사용할 때 라이브러리를 찾을 수 없음 (0) | 2023.07.15 |
문자열에서 모든 공백을 제거하는 방법은 무엇입니까? (0) | 2023.07.15 |
충돌 업데이트 시 삽입 일부 필드를 사용하여 Postgres가 있는 Spring Data/Hibernate 저장 엔티티 (0) | 2023.07.15 |
한 워크북의 시트에서 다른 워크북으로 VBA 코드를 복사하시겠습니까? (0) | 2023.07.15 |