이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
다음에 대한 동일한 페이지를 보고 싶을 수도 있습니다.토토 사이트 PostgreSQL : 문서 : 17 : 41.6. 제어 구조버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

40.6. 스포츠 토토 구조

스포츠 토토 구조는 아마도 가장 유용하고 중요할 것입니다. 의 일부PL/pgSQL. 와 함께PL/pgSQL의 스포츠 토토 구조, 당신은 조작할 수 있다포스트그레SQL데이터 매우 유연하고 강력한 방법입니다.

40.6.1. 에서 돌아오는 중 기능

데이터를 반환할 수 있는 두 가지 명령이 있습니다 함수에서:반환그리고다음으로 돌아가기.

40.6.1.1. 반환

반환표현;

반환표현식으로 종료 함수를 실행하고의 값을 반환합니다.표현발신자에게. 이 양식이 사용됩니다 을 위한PL/pgSQL하지 않는 함수 세트를 반환합니다.

스칼라 유형을 반환하는 함수에서 표현식의 결과는 자동으로 함수의 반환 유형으로 캐스팅됩니다. 과제에 대해 설명된 대로입니다. 하지만 복합(행)을 반환하려면 값을 정확하게 전달하는 표현식을 작성해야 합니다. 요청된 열 집합입니다. 명시적 캐스팅을 사용해야 할 수도 있습니다.

출력 매개변수를 사용하여 함수를 선언한 경우 다음과 같이 작성하세요.반환표현이 없습니다. 현재 출력 매개변수 변수의 값이 반환됩니다.

반환할 함수를 선언한 경우무효, a반환문은 할 수 있습니다 기능을 일찍 종료하는 데 사용됩니다. 하지만 표현은 쓰지 마세요. 수행원반환.

함수의 반환 값은 정의되지 않은 상태로 둘 수 없습니다. 만약에 제어가 함수의 최상위 블록 끝에 도달함 a를 누르지 않고반환성명, a 런타임 오류가 발생합니다. 이 제한사항은 다음에 적용되지 않습니다. 출력 매개변수가 있는 함수와 반환하는 함수무효13015_13045반환다음과 같은 경우 문이 자동으로 실행됩니다. 최상위 블록이 완료됩니다.

일부 예:

-- 스칼라 유형을 반환하는 함수
1 + 2를 반환합니다.
반환 scalar_var;

-- 복합 유형을 반환하는 함수
RETURN 복합_유형_var;
RETURN (1, 2, '3'::텍스트);  -- 올바른 유형으로 열을 캐스팅해야 합니다.

40.6.1.2. 다음으로 돌아가기그리고반환 질문

다음으로 돌아가기표현;
반환 쿼리질의;
쿼리 실행 반환명령어-문자열 [사용 중표현 [, ... ] ];

PL/pgSQL함수는 복귀 선언SETOF어떤 유형, 따라야 할 절차는 다음과 같습니다. 약간 다릅니다. 이 경우 반품할 개별 품목은 의 순서로 지정됩니다.다음으로 돌아가기또는반환 쿼리명령, 그리고 마지막반환인수가 없는 명령은 다음과 같이 사용됩니다. 함수 실행이 완료되었음을 나타냅니다.다음으로 돌아가기스칼라 및 복합 데이터 유형; 복합 결과 유형, 전체"테이블"의 결과가 반환됩니다.반환 쿼리다음 결과를 추가합니다. 함수의 결과 세트에 대한 쿼리를 실행합니다.다음으로 돌아가기그리고반환 질문단일 세트에서 자유롭게 혼합될 수 있습니다. 함수이며, 이 경우 결과는 연결됩니다.

다음으로 돌아가기그리고반환 쿼리실제로는 에서 돌아오지 않습니다. 함수 — 단순히 함수에 0개 이상의 행을 추가합니다. 결과 집합. 그런 다음 실행은의 다음 문으로 계속됩니다.PL/pgSQL함수. 연속적으로다음으로 돌아가기또는반환 질문명령이 실행되면 결과 세트가 구축됩니다. 에이 결정적인반환인수를 사용하면 제어가 함수를 종료하게 됩니다(또는 그냥 놔둘 수도 있습니다). 함수의 끝에 도달하는 제어).

반환 쿼리변형 있음반환 쿼리 실행, 쿼리를 지정합니다. 동적으로 실행됩니다. 매개변수 표현식을 삽입할 수 있습니다. 다음을 통해 계산된 쿼리 문자열사용 중, 에 에서와 같은 방법으로실행명령.

출력 매개변수를 사용하여 함수를 선언한 경우 다음과 같이 작성하세요.다음으로 돌아가기표현이 없습니다. 각각에 실행, 출력 매개변수 변수의 현재 값 최종 반환을 위해 결과 행으로 저장됩니다. 참고하세요 함수를 반환으로 선언해야 합니다.SETOF 레코드여러 개의 출력이 있는 경우 매개변수 또는SETOF어떤 유형출력이 하나만 있는 경우 유형의 매개변수어떤 유형, 에 출력으로 집합 반환 함수를 생성하려면 매개변수.

다음은 다음을 사용하는 함수의 예입니다.다음으로 돌아가기:

CREATE TABLE foo(foid INT, foosubid INT, fooname TEXT);
INSERT INTO foo VALUES (1, 2, '3');
foo 값에 삽입(4, 5, '6');

함수 생성 또는 교체 get_all_foo()는 SETOF foo AS를 반환합니다.
$BODY$
선언하다
    r foo%행유형;
시작하다
    r IN의 경우
        SELECT * FROM foo WHERE fooid  0
    고리
        -- 여기에서 일부 처리를 수행할 수 있습니다.
        다음으로 돌아가기 r; -- SELECT의 현재 행을 반환합니다.
    엔드 스포츠 토토;
    반품;
끝
$BODY$
언어 plpgsql;

SELECT * FROM get_all_foo();

다음은 다음을 사용하는 함수의 예입니다.반환 쿼리:

CREATE FUNCTION get_available_flightid(date) SETOF 정수 AS를 반환합니다.
$BODY$
시작하다
    반환 쿼리 선택 항공편 ID
                   항공편 출발
                  비행 날짜 = $1인 곳
                    AND 항공편 날짜 < ($1 + 1);

    -- 실행이 완료되지 않았으므로 행이 반환되었는지 확인할 수 있습니다.
    -- 그렇지 않은 경우 예외를 발생시킵니다.
    발견되지 않은 경우
        RAISE EXEPTION '%.에 항공편 없음', $1;
    종료하면;

    반품;
 끝
$BODY$
언어 plpgsql;

-- 이용 가능한 항공편을 반환하거나 항공편이 없는 경우 예외 발생
-- 이용 가능한 항공편.
SELECT * FROM get_available_flightid(CURRENT_DATE);

참고:현재 구현다음으로 돌아가기그리고반환 질문에서 반환되기 전에 전체 결과 세트를 저장합니다. 위에서 설명한 대로 기능을 수행합니다. 즉, 만약 aPL/pgSQL함수는 매우 큰 결과를 생성합니다. 설정하면 성능이 저하될 수 있습니다. 데이터가 디스크에 기록됩니다. 메모리 고갈을 방지하지만 함수 자체는 반환되지 않습니다. 전체 결과 집합이 생성될 때까지. 다음 버전의PL/pgSQL사용자가 다음을 수행하도록 허용할 수 있습니다. 이러한 제한이 없는 집합 반환 함수를 정의하세요. 현재 데이터가 디스크에 기록되기 시작하는 시점은 에 의해 제어됨work_mem구성 변수. 메모리가 충분한 관리자 더 큰 결과 세트를 메모리에 저장하려면 증가를 고려해야 합니다. 이 매개변수입니다.

40.6.2. 조건부

IF그리고사례문을 사용하면 특정 기준에 따라 대체 명령을 실행할 수 있습니다. 정황.PL/pgSQL세 개가 있습니다 의 형태IF:

  • 만약 ... 그렇다면

  • IF ... 그렇다면 ... ELSE

  • 만약 ... 그렇다면 ... ELSIF ... 그렇다면 ... 또 다른

그리고 두 가지 형태의사례:

  • 사례 ... 언제 ... 그때 ... ELSE ... 끝 사례

  • CASE WHEN ... THEN ... ELSE ... 끝 사례

40.6.2.1. IF-THEN

IF부울 표현식그때진술END IF;

IF-THEN문이 가장 간단합니다. 의 형태IF. 사이의 진술그때그리고END IF조건이 true일 경우 실행됩니다. 그렇지 않으면 그들은 건너뛰었습니다.

예:

IF v_user_id < 0 THEN
    사용자 업데이트 SET email = v_email WHERE user_id = v_user_id;
종료하면;

40.6.2.2. IF-THEN-ELSE

IF부울 표현식그때문장ELSE문장END IF;

IF-THEN-ELSE문 추가IF-THEN지정할 수 있게 하여 다음과 같은 경우 실행되어야 하는 대체 명령문 세트 조건이 사실이 아닙니다. (여기에는 다음과 같은 경우도 포함됩니다. 조건은 NULL로 평가됩니다.)

예:

IF parentid가 NULL이거나 parentid = ''
그 다음에
    RETURN 전체 이름;
또 다른
    RETURN hp_true_filename(부모 ID) || '/' || 성명;
종료하면;
IF v_count  0 THEN
    INSERT INTO users_count(개수) VALUES(v_count);
    't'를 반환합니다.
또 다른
    'f'를 반환합니다.
종료하면;

40.6.2.3. IF-THEN-ELSIF

IF부울 표현식그때문장
[ELSIF부울 표현식그때문장
[ELSIF부울 표현식그때문장
    ...]]
[ELSE문장 ]
종료하면;

때로는 두 가지 이상의 대안이 있을 수 있습니다.IF-THEN-ELSIF편리한 방법을 제공합니다. 여러 가지 대안을 차례로 확인합니다. 그만큼IF조건은 다음이 될 때까지 연속적으로 테스트됩니다. 첫 번째로 참인 것이 발견되었습니다. 그런 다음 관련 진술 실행된 후 제어는 다음 명령문으로 넘어갑니다. 후에END IF. (모든 후속IF조건은아님테스트했습니다.) 다음 중 어느 것도 해당되지 않는 경우IF조건이 참이면ELSE블록(있는 경우)이 실행됩니다.

다음은 예입니다:

IF 숫자 = 0 THEN
    결과 := '0';
ELSIF 번호  0 THEN
    결과 := '긍정적';
ELSIF 숫자 < 0 THEN
    결과 := '부정';
또 다른
    -- 흠, 유일한 다른 가능성은 숫자가 null이라는 것입니다.
    결과 := 'NULL';
종료하면;

핵심 단어ELSIF철자도 가능함ELSEIF.

동일한 작업을 수행하는 또 다른 방법은 중첩하는 것입니다.IF-THEN-ELSE문에서와 같이 다음 예:

IF deco_row.sex = 'm' THEN
    Pretty_sex := '남자';
또 다른
    IF deco_row.sex = 'f' 그러면
        Pretty_sex := '여자';
    종료하면;
종료하면;

그러나 이 방법은 일치하는 항목을 작성해야 합니다.END IF각각IF그러니까 사용하는 것보다 훨씬 번거롭습니다.ELSIF대안이 많을 때.

40.6.2.4. 단순한사례

사례검색 표현언제표현 [, 표현 [ ... ]] 그러면문장
  [언제표현 [, 표현 [ ... ]] 그럼문장
    ... ]
  [ELSE문장 ]
종료 사례;

간단한 형식사례제공 피연산자의 동일성을 기반으로 한 조건부 실행. 그만큼검색 표현가 평가되고(한 번) 연속적으로 각각 비교표현에서언제절. 일치하는 항목이 발견되면 동문장있습니다 실행된 후 제어는 다음 명령문으로 전달됩니다.END CASE. (다음에)언제표현식은 평가되지 않습니다.) 일치하는 항목이 없는 경우 찾았습니다.ELSE 문장실행됩니다. 하지만 만약에ELSE존재하지 않으면 aCASE_NOT_FOUND예외가 발생했습니다.

다음은 간단한 예입니다:

사례 x
    1, 2일 때
        msg := '하나 또는 둘';
    또 다른
        msg := '1 또는 2 이외의 값';
종료 사례;

40.6.2.5. 검색됨사례

사례
    언제부울 표현식그때문장
  [언제부울 표현식그때문장
    ... ]
  [ELSE문장 ]
종료 사례;

검색된 형태사례제공 부울 표현식의 진실성에 기반한 조건부 실행. 각언제절의부울 표현식순으로 평가되며, 결과를 얻을 때까지. 그 다음에 해당문장있습니다 실행된 후 제어는 다음 명령문으로 전달됩니다.END CASE. (다음에)언제표현식은 평가되지 않습니다.) 그렇지 않은 경우 true 결과가 발견되었습니다.ELSE 문장실행됩니다. 하지만 만약에ELSE존재하지 않는 경우 aCASE_NOT_FOUND예외가 발생했습니다.

다음은 예입니다:

사례
    WHEN x 0과 10 사이 THEN
        msg := '값은 0과 10 사이입니다.';
    언제 x 11시와 20시 사이
        msg := '값은 11에서 20 사이입니다';
종료 사례;

이 형식은사례완전히 에 해당함IF-THEN-ELSIF, 제외 생략된 규칙에 도달함ELSE절은 아무것도 하지 않는 대신 오류를 발생시킵니다.

40.6.3. 단순 스포츠 토토

와 함께스포츠 토토, 종료, 계속, 동안, forFOREACH문장을 준비할 수 있습니다.PL/pgSQL반복하는 함수 일련의 명령입니다.

40.6.3.1. 스포츠 토토

[ <<라벨 ]
고리문장END 스포츠 토토 [ 라벨 ];

스포츠 토토무조건 스포츠 토토를 정의합니다. 에 의해 종료될 때까지 무기한 반복됩니다.종료또는반환성명. 선택사항라벨다음에서 사용할 수 있습니다종료그리고계속중첩 스포츠 토토 내의 명령문을 사용하여 어떤 스포츠 토토를 지정하는지 진술을 참조하십시오.

40.6.3.2. 종료

종료 [ 라벨 ] [언제부울 표현식 ];

아니면라벨주어지면, 가장 안쪽 스포츠 토토가 종료되고 다음 명령문이 나옵니다.END LOOP다음에 실행됩니다. 만약에라벨이 주어지면 이는 다음의 라벨이어야 합니다. 중첩 스포츠 토토 또는 블록의 현재 또는 일부 외부 수준. 그런 다음 명명된 스포츠 토토 또는 블록이 종료되고 제어가 계속됩니다. 스포츠 토토/블록에 해당하는 명령문END.

만약언제이 지정되면 스포츠 토토 종료 경우에만 발생합니다부울 표현식사실입니다. 그렇지 않으면 제어는 다음 문으로 전달됩니다.종료.

종료모든 유형의 제품과 함께 사용할 수 있습니다. 스포츠 토토; 무조건 스포츠 토토와 함께 사용하는 것으로 제한되지 않습니다.

a와 함께 사용하는 경우시작차단,종료다음 명령문으로 제어권을 전달합니다 블록이 끝난 후. 이를 위해서는 라벨을 사용해야 합니다. 목적; 라벨이 없는종료절대 그렇지 않습니다. a와 일치하는 것으로 간주됩니다.시작차단. (이것 8.4 이전 릴리스에서 변경된 사항입니다.PostgreSQL, 라벨이 지정되지 않은종료a와 일치시키다시작차단합니다.)

예:

스포츠 토토
    -- 일부 계산
    IF 개수  0 그러면
        출구;  -- 스포츠 토토 종료
    종료하면;
엔드 스포츠 토토;

고리
    -- 일부 계산
    개수  0일 때 종료합니다.  -- 이전 예제와 동일한 결과
엔드 스포츠 토토;

<<차단
시작하다
    -- 일부 계산
    IF 주식  100000 THEN
        EXIT 블록;  -- BEGIN 블록을 종료합니다.
    종료하면;
    -- 주식  100000인 경우 여기 계산은 건너뜁니다.
끝;

40.6.3.3. 계속

계속 [ 라벨 ] [언제부울 표현식 ];

아니면라벨주어지면 다음 가장 안쪽 스포츠 토토의 반복이 시작됩니다. 즉, 모든 진술은 스포츠 토토 본문에 남아 있는 부분은 건너뛰고 제어는 스포츠 토토 본문으로 돌아갑니다. 다른 스포츠 토토가 있는지 확인하기 위한 스포츠 토토 제어 표현식(있는 경우) 반복이 필요합니다. 만약에라벨이다 현재 실행될 스포츠 토토의 레이블을 지정합니다. 계속되는.

만약언제이 지정되면 다음 스포츠 토토 반복은 다음과 같은 경우에만 시작됩니다.부울 표현식사실입니다. 그렇지 않으면, 제어는 다음 명령문으로 전달됩니다.계속.

계속모든 유형의 제품과 함께 사용할 수 있습니다. 스포츠 토토; 무조건 스포츠 토토와 함께 사용하는 것으로 제한되지 않습니다.

예:

스포츠 토토
    -- 일부 계산
    개수가 100보다 크면 종료합니다.
    개수가 50 미만일 때 계속하세요.
    -- 개수 IN [50 .. 100]에 대한 일부 계산
끝 스포츠 토토;

40.6.3.4. 동안

[ <<라벨 ]
하는 동안부울 표현식스포츠 토토문장END 스포츠 토토 [ 라벨 ];

동안문이 시퀀스를 반복합니다. 다음과 같은 진술의 수:부울 표현식참으로 평가됩니다. 그만큼 표현식은 스포츠 토토 본문의 각 항목 직전에 확인됩니다.

예:

채무 금액  0 AND 선물_증명서 잔액  0 LOOP인 동안
    -- 여기에 몇 가지 계산이 있습니다.
엔드 스포츠 토토;

스포츠 토토가 완료되지 않은 동안
    -- 여기에 몇 가지 계산이 있습니다.
끝 스포츠 토토;

40.6.3.5. for(정수 변형)

[ <<라벨 ]
을 위한이름IN [반전] 표현 .. 표현 [BY표현 ] 스포츠 토토문장END 스포츠 토토 [ 라벨 ];

이 형태는for스포츠 토토를 생성합니다. 정수 값의 범위를 반복합니다. 변수이름자동으로 유형으로 정의됩니다.정수그리고 스포츠 토토 내부에만 존재합니다(모든 변수 이름의 기존 정의는 고리). 하한과 상한을 나타내는 두 표현식 범위는 스포츠 토토에 들어갈 때 한 번 평가됩니다. 만약BY절이 지정되지 않았습니다. 반복 단계는 1입니다. 그렇지 않은 경우에는에 지정된 값입니다.BY절, 스포츠 토토에서 한 번 다시 평가됩니다. 기입. 만약에반전이 지정되면 각 단계 이후에 단계 값을 더하는 것이 아니라 뺍니다. 반복.

정수의 몇 가지 예for스포츠 토토:

i IN 1..10 스포츠 토토용
    -- 스포츠 토토 내에서 1,2,3,4,5,6,7,8,9,10 값을 사용하겠습니다.
엔드 스포츠 토토;

역방향 10..1 스포츠 토토의 i용
    -- 스포츠 토토 내에서 10,9,8,7,6,5,4,3,2,1 값을 사용하겠습니다.
엔드 스포츠 토토;

i에 대한 역방향 10..1 BY 2 스포츠 토토
    -- 스포츠 토토 내에서 10,8,6,4,2 값을 사용하겠습니다.
끝 스포츠 토토;

하한이 상한보다 큰 경우(또는 그 이하) 그보다,반전case), 스포츠 토토 본문 전혀 실행되지 않습니다. 오류가 발생하지 않습니다.

만약에라벨다음에 첨부됨for반복 후 정수 스포츠 토토 변수 이를 사용하여 정규화된 이름으로 참조할 수 있습니다.라벨.

40.6.4. 쿼리를 통한 루핑 결과

다른 유형의 사용for스포츠 토토, 당신은 쿼리 결과를 반복하고 해당 데이터를 조작할 수 있습니다. 따라서. 구문은 다음과 같습니다.

[ <<라벨 ]
을 위한대상IN질의스포츠 토토문장END 스포츠 토토 [ 라벨 ];

대상은 레코드 변수입니다. 행 변수 또는 쉼표로 구분된 스칼라 변수 목록입니다. 그만큼대상연속적으로 할당됨 각 행은질의그리고 스포츠 토토 본문은 각 행에 대해 실행됩니다. 예는 다음과 같습니다.

CREATE FUNCTION cs_refresh_mviews() 정수를 $$로 반환합니다.
선언하다
    mviews 기록;
시작하다
    RAISE NOTICE '구체화된 뷰를 새로 고치는 중...';

    FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP

        -- 이제 "mviews"에는 cs_materialized_views의 레코드가 하나 있습니다.

        RAISE NOTICE '구체화된 뷰 %s 새로 고침 중...', quote_ident(mviews.mv_name);
        'TRUNCATE TABLE' 실행 || quote_ident(mviews.mv_name);
        'INSERT INTO' 실행
                   || quote_ident(mviews.mv_name) || ' '
                   || mviews.mv_query;
    엔드 스포츠 토토;

    RAISE NOTICE '구체화된 뷰 새로 고침이 완료되었습니다.';
    1을 반환합니다.
끝;
$$ 언어 plpgsql;

스포츠 토토가 다음에 의해 종료되는 경우종료문, 마지막으로 할당된 행 값은 이후에도 계속 액세스할 수 있습니다. 스포츠 토토.

질의이러한 유형에 사용됨for문은 다음과 같은 SQL 명령이 될 수 있습니다. 호출자에게 행을 반환합니다.선택이것은 가장 일반적인 경우이지만 다음을 사용할 수도 있습니다.삽입, 업데이트또는삭제돌아오는 중절. 다음과 같은 일부 유틸리티 명령설명역시 작동합니다.

PL/pgSQL변수는 쿼리 텍스트로 대체되고 쿼리 계획이 캐시됩니다. 재사용 가능, 자세한 내용은섹션 40.10.1그리고섹션 40.10.2.

실행 중문장은 또 다른 것입니다 행을 반복하는 방법:

[ <<라벨 ]
을 위한대상실행 중텍스트 표현 [사용 중표현 [, ... ] ] 스포츠 토토문장END 스포츠 토토 [ 라벨 ];

이것은 소스 쿼리가 다음과 같은 점을 제외하면 이전 형식과 같습니다. 평가되고 다시 계획되는 문자열 표현식으로 지정됩니다. 각 항목에 대해for스포츠 토토. 이를 통해 프로그래머는 미리 계획된 쿼리의 속도를 선택하거나 일반 쿼리와 마찬가지로 동적 쿼리의 유연성실행문장. 마찬가지로실행, 매개변수 값을 동적 명령을 통해사용 중.

결과가 다음과 같아야 하는 쿼리를 지정하는 또 다른 방법 반복을 통해 커서로 선언하는 것입니다. 이에 대한 설명은섹션 40.7.4.

40.6.5. 배열을 통한 반복

FOREACH스포츠 토토는 다음과 매우 유사합니다.for스포츠 토토이지만 반복하는 대신 SQL 쿼리에서 반환된 행은 요소를 통해 반복됩니다. 배열 값의 (일반적으로,FOREACH이다 복합 값의 구성 요소를 반복하는 것을 의미합니다. 표현; 배열 외에 합성물을 통한 반복을 위한 변형 향후 추가될 수 있습니다.) TheFOREACH배열을 반복하는 명령문은 다음과 같습니다:

[ <<라벨 ]
FOREACH대상 [슬라이스번호 ] 배열표현스포츠 토토문장END 스포츠 토토 [ 라벨 ];

없이슬라이스또는 만약슬라이스 0이 지정되면 스포츠 토토는 다음을 반복합니다. 를 평가하여 생성된 배열의 개별 요소표현. 그만큼대상변수는 각 요소에 할당됩니다 값을 순서대로 입력하고 스포츠 토토 본문은 각 요소에 대해 실행됩니다. 다음은 정수 요소를 반복하는 예입니다. 정렬:

CREATE FUNCTION sum(int[])는 int8을 $$로 반환합니다.
선언하다
  s int8 := 0;
  x 정수;
시작하다
  FOREACH x IN 배열 $1
  고리
    s := s + x;
  엔드 스포츠 토토;
  반환;
끝;
$$ 언어 plpgsql;

요소는 저장 순서에 관계없이 저장 순서대로 방문됩니다. 배열 차원의 수. 비록대상일반적으로 단일 변수입니다. 배열을 반복할 때 변수 목록이 될 수 있습니다. 복합 값(레코드). 이 경우 각 배열 요소에 대해 변수는 복합의 연속 열에서 할당됩니다. 값.

긍정적으로슬라이스값,FOREACH대신 배열의 조각을 반복합니다. 단일 요소보다 그만큼슬라이스값은 반드시 차원의 수보다 크지 않은 정수 상수여야 합니다. 배열. 그만큼대상변수는 반드시 배열이고 배열 값의 연속적인 조각을 받습니다. 여기서 각 조각은 다음과 같이 지정된 차원 수로 구성됩니다.슬라이스. 다음은 반복의 예입니다. 1차원 조각을 통해:

함수 생성 scan_rows(int[]) $$로 void 반환
선언하다
  x 정수[];
시작하다
  배열 $1의 FOREACH x 슬라이스 1
  고리
    알림 발생 '행 = %', x;
  엔드 스포츠 토토;
끝;
$$ 언어 plpgsql;

SELECT scan_rows(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]);

주의사항: 행 = 1,2,3

40.6.6. 트래핑 오류

기본적으로 a에서 발생하는 모든 오류는PL/pgSQL함수가 실행을 중단합니다. 기능, 실제로 주변 거래도 마찬가지입니다. 너 다음을 사용하여 오류를 포착하고 복구할 수 있습니다.시작다음으로 차단예외절. 구문은 다음의 확장입니다. a의 일반 구문시작차단:

[ <<라벨 ]
[선언선언 ]
시작하다문장예외
    언제조건 [또는조건 ... ] 그럼handler_statements
    [언제조건 [또는조건 ... ] 그럼handler_statements
      ... ]
끝;

오류가 발생하지 않으면 이 블록 형태는 단순히 모든 것을 실행합니다.문장, 그런 다음 제어가 통과됩니다. 이후 다음 문으로END. 하지만 만약 오류가 발생했습니다.문장, 추가 처리문장폐기되었으며 스포츠 토토권이 통과되었습니다. 에예외목록. 목록은 다음과 같습니다 처음으로 검색했습니다조건발생한 오류와 일치합니다. 일치하는 항목이 발견되면 동handler_statements실행된 후 제어는 다음 명령문으로 넘어갑니다.END. 일치하는 항목이 없으면 오류 마치예외절이 전혀 없었습니다. 오류는 블록을 다음으로 묶음:예외또는 다음과 같은 경우 함수 처리를 중단하는 것은 없습니다.

조건이름은 무엇이든 될 수 있습니다. 그 중윈 토토 : 문서 : 9.3 : 윈 토토 윈 토토 코드. 카테고리 이름은 해당 카테고리 내의 모든 오류와 일치합니다. 특별한 조건 이름기타모든 오류와 일치 제외 유형QUERY_CANCELED. (그것은 가능하지만 종종 현명하지 못한 경우가 많습니다.QUERY_CANCELED이름별.) 조건 이름은 대소문자를 구분합니다. 또한 오류 조건은 다음과 같이 지정할 수 있습니다.SQLSTATE코드; 예를 들어 이것들은 동등한:

divide_by_zero 다음에는 ...
SQLSTATE '22012' 다음 ...

선택한 항목 내에서 새로운 오류가 발생하는 경우handler_statements, 잡을 수 없습니다. 이것예외절이지만 전파되었습니다. 밖으로. 주변예외절은 다음과 같습니다. 잡아라.

에 의해 오류가 발견된 경우예외절, 지역 변수PL/pgSQL기능은 이전과 동일하게 유지됩니다. 오류가 발생했지만 영구 데이터베이스 상태에 대한 모든 변경 사항은 블록이 롤백됩니다. 예를 들어, 이것을 고려하십시오 파편:

INSERT INTO mytab(이름, 성) VALUES('톰', '존스');
시작하다
    업데이트 mytab SET 이름 = 'Joe' WHERE 성 = 'Jones';
    x := x + 1;
    y := x / 0;
예외
    WHEN Division_by_zero THEN
        RAISE NOTICE 'divation_by_zero를 포착함';
        반환 x;
끝;

통제가 다음에 대한 할당에 도달할 때y, 다음과 함께 실패합니다.division_by_zero오류. 이것은 다음에 의해 포착될 것입니다.예외절. 에서 반환된 값 그만큼반환진술은 증가된 값x, 하지만 다음의 효과는 그만큼업데이트명령이 롤링되었습니다 뒤쪽에. 그만큼삽입앞의 명령 그러나 블록은 롤백되지 않으므로 최종 결과는 데이터베이스에는 다음이 포함됩니다.톰 존스아님조 존스.

팁:다음을 포함하는 블록예외절은 비용이 훨씬 더 많이 듭니다. 블록이 없는 블록보다 들어가고 나옵니다. 그러므로 사용하지 마십시오.예외필요 없이.

예 40-2. 의 예외업데이트/삽입

이 예에서는 다음 중 하나를 수행하기 위해 예외 처리를 사용합니다.업데이트또는삽입, 적절하게:

CREATE TABLE db(INT 기본 키, b TEXT);

CREATE FUNCTION merge_db(key INT, data TEXT) VOID AS를 반환합니다.
$$
시작하다
    고리
        -- 먼저 키를 업데이트해 보세요.
        업데이트 db SET b = 데이터 WHERE a = 키;
        그렇다면 발견되면
            반품;
        종료하면;
        -- 거기가 없으니 열쇠를 삽입해 보세요
        -- 다른 사람이 동시에 동일한 키를 삽입하는 경우
        -- 고유 키 오류가 발생할 수 있습니다.
        시작하다
            INSERT INTO db(a,b) VALUES(키, 데이터);
            반품;
        고유한 위반이 발생한 경우 예외
            -- 아무것도 하지 않고 스포츠 토토를 반복하여 업데이트를 다시 시도합니다.
        끝;
    엔드 스포츠 토토;
끝;
$$
언어 plpgsql;

SELECT merge_db(1, '데이비드');
SELECT merge_db(1, '데니스');

이 코딩은 다음을 가정합니다.unique_violation오류는 다음에 의해 발생합니다.삽입말하자면, 가 아니라삽입테이블의 트리거 기능에서. 어쩌면 또한 테이블에 고유 인덱스가 두 개 이상 있으면 오작동합니다. 어떤 인덱스가 원인이었는지에 관계없이 작업을 다시 시도하기 때문입니다. 오류. 논의된 기능을 사용하면 더 많은 안전성을 확보할 수 있습니다. 다음으로 트랩된 오류가 예상한 오류인지 확인하세요.

40.6.6.1. 정보 얻기 오류에 대해

예외 처리기는 종종 특정 항목을 식별해야 합니다. 발생한 오류입니다. 에 대한 정보를 얻는 방법에는 두 가지가 있습니다. 현재 예외는PL/pgSQL: 특수 변수 및스택됨 진단명령.

예외 핸들러 내에서 특수 변수SQLSTATE다음에 해당하는 오류 코드가 포함되어 있습니다. 발생한 예외(참조표 A-1목록 가능한 오류 코드). 특수 변수SQLERRM다음과 관련된 오류 메시지가 포함되어 있습니다. 예외. 이 변수는 예외 외부에서 정의되지 않았습니다. 핸들러.

예외 처리기 내에서 정보를 검색할 수도 있습니다. 를 사용하여 현재 예외에 대해GET 누적 진단명령, 형식은 다음과 같습니다.

스택 진단 받기변수 = 항목 [ , ... ];

각각항목키워드입니다 지정된 변수에 할당될 상태 값 식별 (수신하려면 올바른 데이터 유형이어야 합니다) 그만큼 현재 사용 가능한 상태 항목은 다음에 표시됩니다.표 40-1.

표 40-1. 오류 진단 값

이름 유형 설명
RETURNED_SQLSTATE 텍스트 예외의 SQLSTATE 오류 코드
COLUMN_NAME 텍스트 예외 관련 컬럼 이름
CONSTRAINT_NAME 텍스트 예외 관련 제약 조건의 이름
PG_DATATYPE_NAME 텍스트 예외와 관련된 데이터 유형의 이름
MESSAGE_TEXT 텍스트 예외의 기본 메시지 텍스트
TABLE_NAME 텍스트 예외 관련 테이블 이름
SCHEMA_NAME 텍스트 예외 관련 스키마 이름
PG_EXCEPTION_DETAIL 텍스트 예외 세부 메시지 텍스트(있는 경우)
PG_EXCEPTION_HINT 텍스트 예외 힌트 메시지 텍스트(있는 경우)
PG_EXCEPTION_CONTEXT 텍스트 호출 스택을 설명하는 텍스트 줄

예외가 항목에 대한 값을 설정하지 않은 경우 빈 문자열이 반환됩니다.

다음은 예입니다:

선언하다
  text_var1 텍스트;
  text_var2 텍스트;
  text_var3 텍스트;
시작하다
  -- 예외가 발생할 수 있는 일부 처리
  ...
그 외의 경우에는 예외
  스택 진단 받기 text_var1 = MESSAGE_TEXT,
                          text_var2 = PG_EXCEPTION_DETAIL,
                          text_var3 = PG_EXCEPTION_HINT;
끝;