트리거 질문 0 2 3,799

by ahriow [SQLServer] [2024.02.06 13:33:39]


안녕하세요

CREATE TABLE [dbo].[USER](
    [USER_IDX] [int] NULL,  
    [JUMIN] [varchar](20) NULL,
    [GENDER] [char](1) NULL,
    [BIRTH] [char](8) NULL
)
CREATE TABLE [dbo].[JUMIN](
    [USER_IDX] [int] NULL,
    [JUMIN] [varchar](255) NULL
)

위 두 테이블이 있습니다. 

우선 수정되면 안되는 트리거 TRG_JUMIN_SEND 이 아래와 같이 존재합니다.

USER 테이블의 JUMIN 값이 업데이트 되면 JUMIN 테이블에 insert 시키는 트리거입니다.

CREATE TRIGGER [dbo].[TRG_JUMIN_SEND]
   ON  [dbo].[USER]
   AFTER INSERT, UPDATE, DELETE
  
AS 
BEGIN  --//0
	DECLARE @ICNT INT
	DECLARE @DCNT INT

	SET @ICNT = (SELECT COUNT(*) FROM INSERTED)
	SET @DCNT = (SELECT COUNT(*) FROM DELETED)

	IF @ICNT > 0
	BEGIN --//1

		IF @DCNT > 0
		BEGIN --//2
			IF(	UPDATE(JUMIN))
			BEGIN --//3
				INSERT INTO 
				JUMIN(
					USER_IDX,JUMIN
				)
				SELECT  
					USER_IDX,
					JUMIN
				FROM [dbo].[USER] I 
			END --//3
		END--//2
	END--//1
END--//0



아래와 같은 시나리오를 만족시키기 위해 USER 테이블에 트리거를 하나 추가하고싶습니다.

시나리오는 BIRTH 가 insert 되면
gender가 1일 때 2000년생 미만이면 birth + 1 + "000000" 이상이면 birth + 3 + "000000"
gender가 0일 때 2000년생 미만이면 birth + 2 + "000000" 이상이면 birth + 4 + "000000"
위의 식으로
1. JUMIN 컬럼을 업데이트 치고
2. 업데이트가 되었을 때 TRG_JUMIN_SEND 가 실행되서 JUMIN 테이블에 데이터가 삽입되는게 목적입니다.

 

시나리오대로 하고싶어 아래처럼 트리거를 만들어 보았습니다.

CREATE TRIGGER [dbo].[TRG_UPDATE_JUMIN]
ON [dbo].[USER]
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE [dbo].[USER]
    SET
        [JUMIN] = [USER].[BIRTH] +
            CASE 
                WHEN [USER].[BIRTH] < '20000101' AND [USER].[GENDER] = '1' THEN '1'
                WHEN [USER].[BIRTH] < '20000101' AND [USER].[GENDER] = '0' THEN '2'
                WHEN [USER].[BIRTH] >= '20000101' AND [USER].[GENDER] = '1' THEN '3'
                WHEN [USER].[BIRTH] >= '20000101' AND [USER].[GENDER] = '0' THEN '4'
                ELSE [USER].[JUMIN]
            END 
            + '000000'
    FROM [dbo].[USER]
    INNER JOIN INSERTED ON [dbo].[USER].USER_IDX = INSERTED.USER_IDX
    WHERE 
        (
            [dbo].[USER].[BIRTH] = INSERTED.[BIRTH]
            AND (INSERTED.[JUMIN] IS NULL OR LTRIM(RTRIM(INSERTED.[JUMIN])) = '')
        );
END;

insert into [USER](user_idx,birth,gender) values ( 1, '19950101', '1')
insert into [USER](user_idx,birth,gender) values ( 2, '19900101', '0')
insert into [USER](user_idx,birth,gender) values ( 3, '20010101', '1')
insert into [USER](user_idx,birth,gender) values ( 4, '20030101', '0')

위처럼 값을 넣어봤는데 USER 테이블에 값이 insert 되었을 때 정상적으로 JUMIN 컬림이 업데이트가 되지만
USER table--

USER_IDX JUMIN GENDER BIRTH
1 199501011000000 1 19950101
2 199001012000000 0 19900101
3 200101013000000 1 20010101
4 200301014000000 0 20030101

JUMIN 테이블을 확인하니
JUMIN TABLE--

USER_IDX JUMIN
1 199501011000000
1 199501011000000
2 199001012000000
1 199501011000000
2 199001012000000
3 200101013000000
1 199501011000000
2 199001012000000
3 200101013000000
4 200301014000000

위처럼 USER TABLE 에 INSERT 가 될 때마다 USER TABLE의 모든 값들이 JUMIN 테이블에 삽입되는데요.

무슨 문제일까요??
TRG_UPDATE_JUMIN 만 수정해서 정상화 시킬수 있을까요?

 

by 마농 [2024.02.07 09:39:32]

TRG_JUMIN_SEND 의 INSERT ~ SELECT 구문의 FROM 절이 잘못 됬네요.
대상 테이블을 직접 사용할게 아니라
INSERTED 를 이용해야죠.
- 변경전 : FROM [dbo].[USER] I
- 변경후 : FROM INSERTED I


by ahriow [2024.02.07 10:02:17]

와.. 감사합니다

제가 기존에 있는 테이블과 트리거를 간단히 만들어서 테스트해보겠다는 생각에 잘라내다가 
기존 트리거에서 
조건 걸어주기 위해 아래처럼 조인 해놓은걸 버려버리고
FROM [dbo].[USER] U INNER JOIN INSERTED I ON U.USER_IDX = I.USER_IDX 
SEND 트리거는 기존에 만들어져있던거니 맞을거다 생각하며 구렁텅이에 빠져버렸네요 

항상 감사합니다!
새해 복 많이 받으세요!!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입