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

38.6. 스포츠 토토 결과 구조

스포츠 토토 결과 구조가 아마도 가장 유용할 것입니다(그리고 중요) 일부PL/pgSQL. 와 함께PL/pgSQL의 통제 구조를 조작할 수 있습니다.포스트그레SQL매우 유연하고 강력한 방법입니다.

38.6.1. 에서 돌아오는 중 기능

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

38.6.1.1. 반환

반환표현;

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

스칼라 유형을 반환할 때 모든 표현식을 사용할 수 있습니다. 표현식의 결과는 자동으로 할당에 대해 설명한 함수의 반환 유형입니다. 받는 사람 복합(행) 값을 반환하려면 레코드를 작성해야 합니다. 행 변수를표현.

출력 매개변수를 사용하여 함수를 선언한 경우 다음을 작성하십시오. 그냥반환표현이 없습니다. 는 출력 매개변수 변수의 현재 값은 다음과 같습니다. 돌아왔습니다.

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

함수의 반환 값은 정의되지 않은 상태로 둘 수 없습니다. 제어권이 최상위 블록의 끝에 도달한 경우 a를 누르지 않고 함수를 작동합니다.반환문을 작성하면 런타임 오류가 발생합니다. 이 제한은 출력 매개변수가 있는 함수 및 함수에는 적용되지 않음 돌아오는 중공허13360_13396반환문은 자동으로 최상위 블록이 완료되면 실행됩니다.

38.6.1.2. 다음으로 돌아가기그리고반환 쿼리

다음으로 돌아가기표현;
반환 쿼리질의;

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

다음으로 돌아가기그리고반환 쿼리실제로는 에서 돌아오지 않습니다. 함수 - 단순히 0개 이상의 행을 추가합니다. 함수의 결과 세트. 그런 다음 실행은 다음으로 계속됩니다. 의 진술PL/pgSQL함수. 연속적으로다음으로 돌아가기또는반환 쿼리명령은 다음과 같습니다 실행되면 결과 세트가 구축됩니다. 결승전반환15589_15732

출력 매개변수를 사용하여 함수를 선언한 경우 다음을 작성하십시오. 그냥다음으로 돌아가기표현이 없습니다. 각 실행에서 출력 매개변수의 현재 값 변수는 최종 반환을 위해 다음 행으로 저장됩니다. 결과. 함수를 반환하도록 선언해야 합니다.SETOF 레코드여러 개가 있는 경우 출력 매개변수 또는SETOF어떤 유형단 하나뿐인 경우 유형의 출력 매개변수어떤 유형, 출력 매개변수가 있는 설정 반환 함수입니다.

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

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

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

SELECT * FROM getallfoo();

다음을 사용하는 함수에 유의하세요.반환 다음또는반환 쿼리반드시 a에서 테이블 소스로 호출됨발신절.

참고:현재 구현다음으로 돌아가기그리고반환 쿼리반환하기 전에 전체 결과 세트를 저장합니다. 위에서 논의한 것처럼 함수에서. 즉, 만약 에PL/pgSQL함수 매우 큰 결과 세트를 생성하므로 성능이 저하될 수 있습니다. 나쁨: 메모리를 피하기 위해 데이터가 디스크에 기록됩니다. 소모되지만 함수 자체는 다음까지 반환되지 않습니다. 전체 결과 세트가 생성되었습니다. 미래 버전PL/pgSQL사용자는 다음과 같은 집합 반환 함수를 정의할 수 있습니다. 이 제한이 없습니다. 현재 시점은 디스크에 쓰기 시작하는 데이터는 다음에 의해 제어됩니다.work_mem구성 변수. 다음을 보유한 관리자 더 큰 결과 세트를 메모리에 저장하기에 충분한 메모리 이 매개변수를 늘리는 것을 고려해야 합니다.

38.6.2. 조건부

IF문을 사용하면 실행할 수 있습니다. 특정 조건에 따른 명령입니다.PL/pgSQL다섯 가지 형태의IF:

  • 만약 ... 그렇다면

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

  • IF ... THEN ... ELSE IF

  • 만약 ... 그렇다면 ... ELSIF ... 그렇다면 ... 그 외

  • 만약 ... 그렇다면 ... ELSEIF ... 그렇다면 ... 그 외

38.6.2.1. IF-THEN

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

IF-THEN문은 가장 간단한 형태의IF. 진술 사이그때그리고END IF조건이 다음과 같으면 실행됩니다. 사실. 그렇지 않으면 건너뜁니다.

예:

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

38.6.2.2. IF-THEN-ELSE

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

IF-THEN-ELSE문 추가IF-THEN다음을 지정할 수 있게 하여 다음과 같은 경우 실행되어야 하는 대체 명령문 세트 조건이 false로 평가됩니다.

예:

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

38.6.2.3. IF-THEN-ELSE IF

IF문은 다음과 같이 중첩될 수 있습니다. 다음 예에서는:

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

이 양식을 사용하면 실제로 중첩됩니다.IF내부 진술ELSE외부의 일부IF성명. 따라서 하나가 필요합니다.END IF중첩된 각 명령문IF그리고 하나는 부모용IF-ELSE. 이것은 실행 가능하지만 지루해집니다. 확인할 대안이 많을 때. 따라서 다음 양식.

38.6.2.4. IF-THEN-ELSIF-ELSE

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

IF-THEN-ELSIF-ELSE제공 여러 대안을 한 번에 확인하는 보다 편리한 방법 성명. 기능적으로는 중첩과 동일합니다.IF-THEN-ELSE-IF-THEN명령은 하나뿐임END IF필요합니다.

다음은 예입니다:

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

38.6.2.5. IF-THEN-ELSEIF-ELSE

ELSEIF는의 별칭입니다.ELSIF.

38.6.3. 단순 스포츠 토토 결과

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

38.6.3.1. 스포츠 토토 결과

[ <<라벨 ]
스포츠 토토 결과문장END 스포츠 토토 결과 [ 라벨 ];

스포츠 토토 결과무조건을 정의합니다. 에 의해 종료될 때까지 무한 반복되는 스포츠 토토 결과종료또는반환문. 선택사항라벨사용할 수 있는 대상종료그리고계속중첩 스포츠 토토 결과의 문을 사용하여 어떤 스포츠 토토 결과를 문을 적용해야 합니다.

38.6.3.2. 종료

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

아니면라벨이 주어지면 가장 안쪽 스포츠 토토 결과가 종료되고 다음 명령문이 나옵니다.END LOOP다음에 실행됩니다. 만일라벨주어진 경우 반드시 현재 또는 중첩 스포츠 토토 결과의 외부 수준의 레이블 또는 차단. 그런 다음 명명된 스포츠 토토 결과나 블록이 종료되고 스포츠 토토 결과/블록 다음의 명령문으로 제어가 계속됩니다. 해당END.

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

종료모든 유형에 사용할 수 있습니다. 스포츠 토토 결과; 무조건 스포츠 토토 결과와 함께 사용하는 것으로 제한되지 않습니다. a와 함께 사용하는 경우시작차단,종료제어권을 다음으로 넘김 블록 끝 뒤에 오는 명령문입니다.

예:

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

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

시작
    -- 일부 계산
    IF 주식  100000 THEN
        종료;  -- BEGIN 블록을 종료합니다.
    종료하면;
끝;

38.6.3.3. 계속

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

아니면라벨주어지면, 가장 안쪽 스포츠 토토 결과의 다음 반복이 시작됩니다. 즉, 모두 스포츠 토토 결과 본문에 남아 있는 명령문은 건너뜁니다. 제어는 스포츠 토토 결과 제어 표현식(있는 경우)으로 돌아가서 또 다른 스포츠 토토 결과 반복이 필요한지 여부를 결정합니다. 만일라벨존재합니다. 실행될 스포츠 토토 결과의 레이블을 지정합니다. 계속됩니다.

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

계속모두와 함께 사용할 수 있습니다. 스포츠 토토 결과 유형; 무조건적으로 사용하도록 제한되지는 않습니다. 스포츠 토토 결과.

예:

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

38.6.3.4. 동안

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

동안문은 다음을 반복합니다.부울 표현식참으로 평가됩니다. 스포츠 토토 결과의 각 항목 직전에 표현식이 검사됩니다. 몸.

예:

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

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

38.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 값을 사용하겠습니다.
끝 스포츠 토토 결과;

하한이 상한보다 큰 경우(또는 미만, 에서반전사례), 스포츠 토토 결과 본문이 전혀 실행되지 않습니다. 오류가 발생하지 않습니다.

만약에라벨다음에 첨부됨for스포츠 토토 결과 다음 정수 스포츠 토토 결과 변수는 다음을 사용하여 정규화된 이름으로 참조될 수 있습니다.라벨.

38.6.4. 쿼리를 통한 루핑 결과

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

[ <<라벨 ]
에 대한대상IN질의스포츠 토토 결과문장END 스포츠 토토 결과 [ 라벨 ];

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

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

    FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP

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

        PERFORM cs_log('구체화된 뷰 새로 고침' || quote_ident(mviews.mv_name) || ' ...');
        'TRUNCATE TABLE' 실행 || quote_ident(mviews.mv_name);
        'INSERT INTO' 실행 || quote_ident(mviews.mv_name) || ' ' || mviews.mv_query;
    엔드 스포츠 토토 결과;

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

스포츠 토토 결과가 다음에 의해 종료되는 경우종료문, 마지막으로 할당된 행 값은 다음과 같습니다. 스포츠 토토 결과 후에도 여전히 액세스 가능합니다.

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

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

실행 중문은 다음과 같습니다 행을 반복하는 또 다른 방법:

[ <<라벨 ]
에 대한대상실행 중텍스트 표현스포츠 토토 결과문장END 스포츠 토토 결과 [ 라벨 ];

이것은 소스 쿼리를 제외하고 이전 양식과 같습니다. 문자열 표현식으로 지정됩니다. 이는 평가되고 각 항목에 대해 다시 계획되었습니다.for스포츠 토토 결과. 이를 통해 프로그래머는 속도를 선택할 수 있습니다. 미리 계획된 쿼리 또는 동적 쿼리의 유연성 일반으로실행진술.

38.6.5. 트래핑 오류

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

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

오류가 발생하지 않으면 이 블록 형태는 단순히 모든 것을 실행합니다.문장그리고 나서 제어는 다음 명령문으로 전달됩니다.END. 그러나 내에서 오류가 발생하면문장, 추가 처리 의문장버려졌고, 스포츠 토토 결과는예외목록. 목록이 처음으로 검색됩니다.조건다음 오류와 일치합니다. 발생했습니다. 일치하는 항목이 발견되면 해당handler_statements실행된 다음 제어는 다음 명령문으로 전달됩니다.END. 일치하는 항목이 없으면 오류가 전파됩니다. 마치예외절 전혀 없었습니다. 오류는 둘러싸서 잡을 수 있습니다. 다음으로 차단예외또는 있는 경우 없음 함수 처리를 중단합니다.

조건이름은 다음과 같습니다. 다음 중 하나에 표시됨Postgre젠 토토 : 문서 : 8.3 : Postgre젠 토토 오류 코드. 카테고리 이름은 해당 카테고리 내의 모든 오류와 일치합니다. 특수 조건 이름기타다음을 제외한 모든 오류 유형과 일치합니다.QUERY_CANCELED. (가능하지만 종종 현명하지 못한, 함정에 빠뜨리다QUERY_CANCELED작성자 이름.) 조건 이름은 대소문자를 구분하지 않습니다.

선택한 항목 내에서 새로운 오류가 발생하는 경우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, 하지만 의 효과업데이트명령은 롤백되었습니다.삽입39948_40064톰 존스아님조 존스.

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

예외 핸들러 내에서,SQLSTATE변수에는 다음과 같은 오류 코드가 포함되어 있습니다. 발생한 예외에 해당합니다(참조표 A-1에 대한 가능한 오류 코드 목록). 그만큼SQLERRM변수에 오류 메시지가 포함되어 있습니다. 예외와 관련이 있습니다. 이 변수는 정의되지 않았습니다. 외부 예외 처리기.

예 38-1. 의 예외업데이트/삽입

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

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, '데니스');