EXCEPTION(Snowflake Scripting)

Snowflake Scripting 블록에서 발생한 예외를 처리하는 방법을 지정합니다.

예외에 대한 자세한 내용은 예외 처리하기 섹션을 참조하십시오.

참고 항목

RAISE

구문

EXCEPTION
    WHEN <exception_name> [ OR <exception_name> ... ] THEN
        <statement>;
        [ <statement>; ... ]
    [ WHEN ... ]
    [ WHEN OTHER THEN ]
        <statement>;
        [ <statement>; ... ]
Copy

여기서:

exception_name

현재 블록의 DECLARE 부분 또는 둘러싸는 블록에 정의된 예외 이름입니다.

statement

문은 다음 중 하나일 수 있습니다.

  • 단일 SQL 문(CALL 포함).

  • 제어 흐름 문(예: 루핑 또는 분기 문).

  • 중첩 블록.

사용법 노트

  • 블록 은 고유한 예외 처리기를 가질 수 있습니다.

  • Snowflake는 블록당 둘 이상의 예외 처리기를 지원하지는 않습니다. 그러나 해당 처리기는 둘 이상의 WHEN 절을 사용하여 둘 이상의 예외 타입을 포착할 수 있습니다.

  • 예외 처리기는 블록 끝에 있어야 합니다. 블록에 예외 처리기 뒤에 문이 포함되어 있으면 해당 문이 실행되지 않습니다.

  • WHEN OTHER THEN 절은 아직 지정되지 않은 예외를 포착합니다.

  • 둘 이상의 WHEN 절이 특정 예외와 일치할 수 있는 경우, 일치하는 첫 번째 WHEN 절이 실행되는 절입니다. 다른 절은 실행되지 않습니다.

  • 지정된 예외가 범위 내에 있는 경우에만 예외 처리기는 지정된 예외를 처리할 수 있습니다.

  • 저장 프로시저가 값을 반환하려는 경우, 예외 처리기의 WHEN 절을 포함하여 가능한 각 경로에서 값을 반환해야 합니다.

이 예에서는 예외를 선언하고, 발생시키고, 처리합니다. 참고:

  • 예외 처리기는 둘 이상의 예외 타입을 처리하도록 설계되었습니다.

  • 예외 처리기의 WHEN 절 중 하나에는 단일 문이 포함되는 한편, 나머지 절에는 블록 이 포함됩니다.

    DECLARE
      RESULT VARCHAR;
      EXCEPTION_1 EXCEPTION (-20001, 'I caught the expected exception.');
      EXCEPTION_2 EXCEPTION (-20002, 'Not the expected exception!');
    BEGIN
      RESULT := 'If you see this, I did not catch any exception.';
      IF (TRUE) THEN
        RAISE EXCEPTION_1;
      END IF;
      RETURN RESULT;
    EXCEPTION
      WHEN EXCEPTION_2 THEN
        RETURN SQLERRM;
      WHEN EXCEPTION_1 THEN
        RETURN SQLERRM;
    END;
    
    Copy

    참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

    EXECUTE IMMEDIATE $$
        DECLARE
            RESULT VARCHAR;
            EXCEPTION_1 EXCEPTION (-20001, 'I caught the expected exception.');
            EXCEPTION_2 EXCEPTION (-20002, 'Not the expected exception!');
        BEGIN
            RESULT := 'If you see this, I did not catch any exception.';
            IF (TRUE) THEN
                RAISE EXCEPTION_1;
            END IF;
            RETURN RESULT;
        EXCEPTION
            WHEN EXCEPTION_2 THEN
                RETURN SQLERRM;
            WHEN EXCEPTION_1 THEN
                RETURN SQLERRM;
        END;
    $$
    ;
    
    Copy

다음은 예외를 발생시키는 예를 실행한 결과입니다. 이는 예외 처리기가 예외를 포착했음을 보여줍니다.

+----------------------------------+
| anonymous block                  |
|----------------------------------|
| I caught the expected exception. |
+----------------------------------+
Copy

이 다음 예는 이전 예와 유사하지만, 중첩 블록을 나타내며, 내부 블록이 내부 블록이나 외부 블록에서 선언된 예외를 발생시킬 수 있음을 보여줍니다.

DECLARE
  e1 EXCEPTION (-20001, 'Exception e1');

BEGIN
  -- Inner block.
  DECLARE
    e2 EXCEPTION (-20002, 'Exception e2');
    selector BOOLEAN DEFAULT TRUE;
  BEGIN
    IF (selector) THEN
      RAISE e1;
    ELSE
      RAISE e2;
    END IF;
  END;

EXCEPTION
  WHEN e1 THEN
    RETURN SQLERRM || ' caught in outer block.';
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
    DECLARE
        e1 EXCEPTION (-20001, 'Exception e1');

    BEGIN
        -- Inner block.
        DECLARE
            e2 EXCEPTION (-20002, 'Exception e2');
            selector BOOLEAN DEFAULT TRUE;
        BEGIN
            IF (selector) THEN
                RAISE e1;
            ELSE
                RAISE e2;
            END IF;
        END;

    EXCEPTION
        WHEN e1 THEN
            BEGIN
                RETURN SQLERRM || ' caught in outer block.';
            END;

    END;
$$
;
Copy

다음은 예외를 발생시키는 예를 실행한 결과입니다. 이는 예외 처리기가 예외를 포착했음을 보여줍니다.

+-------------------------------------+
| anonymous block                     |
|-------------------------------------|
| Exception e1 caught in outer block. |
+-------------------------------------+
Copy

이 다음 예는 이전 예와 유사하지만, 각각 고유한 예외 처리기가 있는 중첩 블록을 나타냅니다.

DECLARE
  RESULT VARCHAR;
  e1 EXCEPTION (-20001, 'Outer exception e1');

BEGIN
  RESULT := 'No error so far (but there will be).';

  DECLARE
    e1 EXCEPTION (-20101, 'Inner exception e1');
  BEGIN
    RAISE e1;
  EXCEPTION
    WHEN e1 THEN
      RESULT := 'Inner exception raised.';
      RETURN RESULT;
  END;

  RETURN RESULT;

EXCEPTION
  WHEN e1 THEN
    RESULT := 'Outer exception raised.';
    RETURN RESULT;

END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
    DECLARE
        RESULT VARCHAR;
        e1 EXCEPTION (-20001, 'Outer exception e1');

    BEGIN
        RESULT := 'No error so far (but there will be).';

        DECLARE
            e1 EXCEPTION (-20101, 'Inner exception e1');
        BEGIN
            RAISE e1;
        EXCEPTION
            WHEN e1 THEN
                RESULT := 'Inner exception raised.';
                RETURN RESULT;
        END;

        RETURN RESULT;

    EXCEPTION
        WHEN e1 THEN
            RESULT := 'Outer exception raised.';
            RETURN RESULT;

    END;
$$
;
Copy

참고

이 예에서는 외부 및 내부 블록에서 같은 예외 이름(e1)을 사용합니다.

이는 권장되지 않습니다.

이 예에서는 예외 이름의 범위 를 설명하기 위해 이 작업을 수행합니다. e1 이름이 있는 두 예외는 다른 예외입니다.

외부 블록의 e1 핸들러는 내부 블록에서 선언되어 발생한 예외 e1을 처리하지 않습니다.

다음은 예외를 발생시키는 예를 실행한 결과입니다. 이는 내부 예외 처리기가 실행되었음을 보여줍니다.

+-------------------------+
| anonymous block         |
|-------------------------|
| Inner exception raised. |
+-------------------------+
Copy

이 예 조각은 다음을 보여줍니다.

  • OR 을 사용하여 동일 절에서 둘 이상의 예외를 포착하는 방법.

  • WHEN OTHER THEN 을 사용하여, 지정되지 않은 예외를 포착하는 방법.

    EXCEPTION
      WHEN MY_FIRST_EXCEPTION OR MY_SECOND_EXCEPTION OR MY_THIRD_EXCEPTION THEN
        RETURN 123;
      WHEN MY_FOURTH_EXCEPTION THEN
        RETURN 4;
      WHEN OTHER THEN
        RETURN 99;
    
    Copy

다음 예에서는 예외를 포착할 때 SQLCODE, SQLERRM(SQL 오류 메시지), SQLSTATE를 반환하는 방법을 보여줍니다.

DECLARE
  MY_EXCEPTION EXCEPTION (-20001, 'Sample message');
BEGIN
  RAISE MY_EXCEPTION;
EXCEPTION
  WHEN STATEMENT_ERROR THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'STATEMENT_ERROR',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
  WHEN EXPRESSION_ERROR THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'EXPRESSION_ERROR',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
  WHEN OTHER THEN
    RETURN OBJECT_CONSTRUCT('Error type', 'Other error',
                            'SQLCODE', SQLCODE,
                            'SQLERRM', SQLERRM,
                            'SQLSTATE', SQLSTATE);
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
    DECLARE
        MY_EXCEPTION EXCEPTION (-20001, 'Sample message');
    BEGIN
        RAISE MY_EXCEPTION;
    EXCEPTION
        WHEN STATEMENT_ERROR THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'STATEMENT_ERROR',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
        WHEN EXPRESSION_ERROR THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'EXPRESSION_ERROR',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
        WHEN OTHER THEN
            RETURN OBJECT_CONSTRUCT('Error type', 'Other error',
                                    'SQLCODE', SQLCODE,
                                    'SQLERRM', SQLERRM,
                                    'SQLSTATE', SQLSTATE);
    END;
$$
;
Copy

이 예를 실행하면 다음 출력이 생성됩니다.

+--------------------------------+
| anonymous block                |
|--------------------------------|
| {                              |
|   "Error type": "Other error", |
|   "SQLCODE": -20001,           |
|   "SQLERRM": "Sample message", |
|   "SQLSTATE": "P0001"          |
| }                              |
+--------------------------------+
Copy

이 예에서는 가능한 경로에서 값을 반환하는 방법을 보여줍니다.

declare
    e1 exception;
    e2 exception;
begin
    statement_1;
    ...
    RETURN x;
exception
    when e1 then begin
        ...
        RETURN y;
        end;
    when e2 then begin
        ...
        RETURN z;
        end;
end;
Copy