* Powerbuilder 10.5


저번 강의에서는 dw_emp 의 유저 이벤트 ue_empno_next 를 만들어 봤습니다.

dw_emp 의 유저 이벤트 ue_save 를 만들어 봅니다.




여기에 다음과 같은 스크립트를 작성합니다.

 

 

38 강에서 다룬 내용이네요.
GetNextModified 함수와 DO LOOP WHILE 문입니다.

li_a 는 0 으로 초기화되므로 GetNextModified 함수는 첫번째 로우부터 수정된 로우를 스캔합니다.

GetNextModified 함수는 수정된 로우가 없을 경우 0 을 반환하므로 li_f > 0 이면 수정된 로우가 있다는 뜻이 됩니다.

li_a = li_f  는 다음 루프 때 방금 찾은 로우 다음부터 스캔하게 합니다.


li_f > 0 인 동안만 루프가 계속해서 진행됩니다.
li_f = 0 이면 루프에서 빠져나가겠죠?

dw_emp 에서 첫번째 로우부터 스캔해서 순차적으로 수정된 로우를 찾는 루틴입니다. 




위 스크립트가 이해 되었다면 다음 스크립트 작성~

 


요거는 39강, 40강에서 다루었습니다.

수정된 로우의 전체 수정상태를 체크해서 NewModified!
(새로운 로우 추가 후 데이터 입력) 라면.... 이라는 뜻이죠.


다음 스크립트 작성~


int li_a, li_f
int li_empno_next    // 추가한 부분

DO
    li_f = dw_emp.GetNextModified(li_a, Primary!)

    If li_f > 0 Then

        // 수정된 로우 관련 작업 블럭
        if dw_emp.GetItemStatus(li_f, 0, Primary!) = NewModified! then

          li_empno_next = dw_emp.Event ue_empno_next()    // 추가한 부분

            dw_emp.SetItem(li_f, 'emp_empno', li_empno_next) // 추가한 부분

        end if
        //--

        li_a = li_f

    End If

LOOP WHILE li_f > 0




dw_emp.Event ue_empno_next()

요거 요거...생소하시죠?

함수를 호출할 때는 그냥 함수명만 작성하면 그만입니다만 이벤트를 호출할 때는 형식이 필요합니다.

컨트롤명.Event 이벤트명

dw_emp.Event ue_empno_next() 라고 하면 dw_emp 의 ue_empno_next 이벤트를 호출합니다.

dw_emp.Trigger Event ue_empno_next() 와 동일합니다.

Trigger즉시 호출하는 것을 뜻합니다. 그럼 나중에 호출하는 것도 있겠네요? 

Trigger 대신 Post 를 쓰면 해당 이벤트를 작성하는 이벤트...여기서는 dw_emp.ue_save 이벤트가 되겠네요.

이 이벤트의 다른 스크립트가 실행되고 난 다음 마지막에 호출됩니다.

 

그러나 Post Event 는 결과값을 반환하지 않으므로 여기서는 적당하지 않습니다.



정리하자면

dw_emp.Trigger Event ue_empno_next()
dw_emp.Event ue_empno_next()

이 둘은 동일합니다.

dw_emp.Post Event ue_empno_next()

는 이 스크립트를 작성하는 이벤트의 다른 스크립트가 실행되고 난 다음 마지막에 호출되지만 결과값을 반환하지 않으므로 여기서는 적당하지 않습니다.

Tip)
dw_emp.TriggerEvent ('ue_empno_next') 이렇게 작성할 수도 있는데요.
dw_emp.Trigger Event ue_empno_next() 와 동일해 보여도 좀 다릅니다.
dw_emp.Trigger Event ue_empno_next() 는 ue_empno_next() 에서 정의된 반환값을 반환하지만
dw_emp.TriggerEvent ('ue_empno_next') 는 성공시 1, 실패시 -1 을 반환합니다.

 

dw_emp.Post Event ue_empno_next() 는 결과값을 반환하지 않지

dw_emp.PostEvent ('ue_empno_next') 는 성공시 True, 실패시 False 를 반환합니다.



li_empno_next = dw_emp.Event ue_empno_next()

는 결국 empno 값을 DB 에서 가져와서 li_empno_next 에 저장합니다.

만약 사용자가 사원을 연속으로 여러명 입력한 뒤에 저장할 경우 empno 가 모두 동일하게 되어 에러가 발생합니다.

그래서 다음과 같이 작성합니다.
(굵게 표시한 부분이 추가한 스크립트)

int li_a, li_f

 

int li_empno_next

 

DO

    li_f = dw_emp.GetNextModified(li_a, Primary!)

    If li_f > 0 Then

        // 수정된 로우 관련 작업 블럭
        If dw_emp.GetItemStatus(li_f, 0, Primary!) = NewModified! then

            If li_empno_next = 0 then   // 최초로 찾은 NewModified! 로우
                li_empno_next = dw_emp.Event ue_empno_next()
            Else
                li_empno_next ++    // 다음에 찾은 NewModified! 로우 부터는 li_empno_next + 1
            End If
   
            dw_emp.SetItem(li_f, 'emp_empno', li_empno_next)

        end if
        //--

        li_a = li_f

    End If

LOOP WHILE li_f > 0


이제 dw_emp.ue_save 이벤트 스크립트 작성은 끝났습니다. 이 이벤트를 호출만 하면 되는데요.

저장할 시점에 호출해야 하므로 cb_save.clicked (저장버튼의 클릭) 이벤트를 엽니다.

 

 



 

 

 

 

 

 

 

 


여기서 호출했습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


실행해서 테스트해 보세요.

 

 



추가버튼을 여러번 클릭해서 테스트하면 됩니다. 그리고 저장하면?

 



이렇게 empno 가 입력 됩니다.


이 프로그램에서 두 명 이상의 사용자가 새로운 사원을 추가한 후에 동시에 저장 버튼을 누른다면 어떻게 될까요?

확률은 비록 낮아도 에러가 발생할 수 있습니다.

그러므로 실전에서는 여러 명이 동시에 작업하면서 새로운 로우를 추가하는 프로그램의 경우

테이블의 PK 칼럼을 AutoIncrement 기능을 사용해서 입력합니다.

PK 칼럼을 사용자가 입력하지 않고 DBMS 에서 자동으로 값을 부여하는 것을 뜻합니다.

MySQL 은 AutoIncrement 기능이 있는데요. 오라클의 경우 Sequence 를 활용하면 됩니다.

자세한 내용은 오라클 Sequence 를 찾아서 공부하세요.

수고하셨습니다.

 

Posted by A4M
,