프로그래밍데이터베이스 개발자

저장 프로시저(SQL)에서 효율적인 오류 처리 및 디버깅 프로시저를 어떻게 구현할 수 있습니까? 오류를 포착하고 로그를 기록하는 데 어떤 메커니즘이 제공됩니까? 이러한 접근 방식이 다양한 DBMS에서 다릅니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

저장 프로시저에서는 특별한 구조를 사용하여 오류를 처리할 수 있으며 이는 필수적입니다.

SQL Server에서 주요 메커니즘은 TRY...CATCH 블록입니다. 모든 오류는 TRY 내에서 포착되고, CATCH에서 세부사항을 기록할 수 있습니다. ERROR_NUMBER(), ERROR_MESSAGE()와 같은 함수가 세부 정보를 가져오는 데 사용됩니다.

BEGIN TRY -- 위험한 작업 UPDATE Accounts SET balance = balance - 100 WHERE id = 1; END TRY BEGIN CATCH INSERT INTO ErrorLog( ErrorTime, ErrorNumber, ErrorMessage, UserName ) VALUES ( GETDATE(), ERROR_NUMBER(), ERROR_MESSAGE(), SUSER_SNAME() ); -- 추가 복구 또는 ROLLBACK END CATCH

Oracle에서는 EXCEPTION 블록을 더 많이 사용합니다:

BEGIN UPDATE ...; EXCEPTION WHEN OTHERS THEN INSERT INTO error_log VALUES (..., SQLERRM); END;

기억해야 할 사항:

  • 모든 오류가 CATCH로 처리되지 않습니다. 예를 들어, 구문 분석 또는 컴파일 오류는 TRY에 들어가기 전에 트랜잭션을 롤백합니다.
  • 정보를 로깅하려면 오류 전용 테이블이 필요합니다.
  • 가능한 한 많은 것을 로깅해야 합니다: 오류 메시지, 번호, 사용자 이름, 작업 매개변수.
  • 다양한 DBMS 간에 구문과 기능이 다릅니다.

함정 질문.

CATCH 블록에서의 예외가 오류 컨텍스트 손실로 이어질 수 있습니까? 중첩 오류 처리를 어떻게 구현할 수 있습니까?

답변 및 예: CATCH 블록에서 오류가 발생하면(예: ErrorLog 테이블에 접근할 수 없는 경우) 원래 오류 컨텍스트가 손실되며 실패 원인에 대한 정보가 사라질 수 있습니다.

이를 예방하기 위해, 로깅을 별도의 프로시저에 캡슐화하여 자체적으로 TRY...CATCH를 포함하여 항상 "오류 처리기에서의 오류"를 포착할 수 있도록 합니다.

BEGIN TRY -- 기본 코드 END TRY BEGIN CATCH EXEC LogError @Error = ERROR_MESSAGE(); END CATCH -- LogError 프로시저 자체에 TRY...CATCH가 포함되어 있습니다

사례

프로젝트: 재무 보고. 저장 프로시저에 TRY...CATCH 블록을 추가했지만 오류가 발생했을 때 매개변수를 로깅하지 않았습니다. 그 결과, 심각한 실패를 포착할 때마다 백업에서 수동으로 상황을 찾아야 했고, 원인(root cause)은 분명치 않았습니다.


사례

프로젝트: 문서 관리 자동화 (Oracle). EXCEPTION 블록에서 사용자 이름 로깅을 잊었습니다. 일주일 동안 조사 후 누군가 의도적으로 문서를 "깨뜨렸다"는 것을 알게 되었고, 감사 로그에서 간접적인 증거로만 확인할 수 있었습니다.


사례

프로젝트: E-commerce. 오류가 발생할 경우 프로시저는 ErrorLog에 오류 메시지를 기록했습니다. 하지만 어느 날, 로그 테이블이 커진 트랜잭션에 의해 잠겼고, 로깅 시도의 중첩 오류가 발생하여 원래 원인을 덮어쓰고 오류 스택을 지우게 되었습니다. 심각한 실패를 위한 추가 테이블과 다단계 로깅을 통해 수정했습니다.