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

36.7. 토토 사이트 순위 구조

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

36.7.1. 에서 돌아오는 중 기능

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

36.7.1.1. 반환

반환표현;

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

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

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

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

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

36.7.1.2. 다음으로 돌아가기

다음으로 돌아가기표현;

PL/pgSQL함수 복귀가 선언되었습니다SETOF어떤 유형, 따라야 할 절차 약간 다릅니다. 이 경우 개별 항목은 반환은에 지정됩니다.다음으로 돌아가기명령, 그리고 마지막반환14150_14252반환 다음스칼라 데이터와 복합 데이터 모두에 사용할 수 있습니다. 유형; 복합 결과 유형, 전체"테이블"개 결과가 반환됩니다.

다음으로 돌아가기실제로는 그렇지 않습니다 함수에서 반환 — 단순히 값을 저장합니다. 표현. 그런 다음 실행은 다음으로 계속됩니다. 의 진술PL/pgSQL함수. 연속적으로다음으로 돌아가기명령이 실행되면 결과 세트가 구축됩니다. 결승전반환인수를 사용하면 제어가 함수를 종료하게 됩니다(또는 다음을 수행할 수 있습니다). 제어가 함수의 끝에 도달하도록 놔두세요.)

출력 매개변수를 사용하여 함수를 선언한 경우 다음을 작성하십시오. 단지다음으로 돌아가기표현이 없습니다. 출력 매개변수 변수의 현재 값은 최종 반환을 위해 저장됩니다. 다음을 선언해야 합니다. 복귀하는 역할을 함SETOF 레코드여러 개의 출력 매개변수가 있는 경우 또는SETOF어떤 종류유형의 출력 매개변수가 하나만 있는 경우어떤 종류, 출력 매개변수가 있는 설정 반환 함수입니다.

사용하는 함수다음으로 돌아가기다음과 같은 방식으로 호출되어야 합니다:

SELECT * some_func()에서 선택;

즉, 함수는 테이블 소스로 사용되어야 합니다.발신절.

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

36.7.2. 조건부

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

  • 만약 ... 그렇다면

  • 만약 ... 그렇다면 ... ELSE

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

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

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

36.7.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;
종료하면;

36.7.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'를 반환합니다.
종료하면;

36.7.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. 이것은 실행 가능하지만 지루해집니다. 확인할 대안이 많을 때. 따라서 다음 양식.

36.7.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';
종료하면;

36.7.2.5. IF-THEN-ELSEIF-ELSE

ELSEIF는의 별칭입니다.ELSIF.

36.7.3. 단순한 토토 사이트 순위

와 함께토토 사이트 순위, 종료, 계속, 동안for문장을 준비할 수 있습니다.PL/pgSQL반복하는 함수 일련의 명령입니다.

36.7.3.1. 토토 사이트 순위

[ <<라벨 ]
고리문장END 토토 사이트 순위 [ 라벨 ];

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

36.7.3.2. 종료

종료 [ 라벨 ] [언제표현 ];

아니면라벨주어지면, 가장 안쪽 토토 사이트 순위가 종료되고 다음 명령문이 나옵니다.END LOOP다음에 실행됩니다. 만약에라벨주어진 것이어야 합니다. 현재 또는 중첩 토토 사이트 순위의 외부 수준의 레이블 또는 차단. 그런 다음 명명된 토토 사이트 순위나 블록이 종료되고 토토 사이트 순위/블록 다음의 명령문으로 제어가 계속됩니다. 동END.

만약언제이 지정되면 토토 사이트 순위가 종료는 다음 경우에만 발생합니다.표현사실입니다. 그렇지 않으면 토토 사이트 순위 이후 명령문으로 전달됩니다.종료.

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

예:

토토 사이트 순위
    -- 일부 계산
    IF 개수  0 그러면
        출구;  -- 토토 사이트 순위 종료
    종료하면;
엔드 토토 사이트 순위;

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

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

36.7.3.3. 계속

계속 [ 라벨 ] [언제표현 ];

아니면라벨주어지면, 가장 안쪽 토토 사이트 순위의 다음 반복이 시작됩니다. 즉, 제어는 토토 사이트 순위 제어 표현식으로 다시 전달됩니다(인 경우 any), 토토 사이트 순위 본문이 재평가됩니다. 만약에라벨존재하는 경우 다음을 지정합니다. 실행이 계속될 토토 사이트 순위의 라벨입니다.

만약언제이 지정되면 다음 토토 사이트 순위 반복은 다음과 같은 경우에만 시작됩니다.표현사실입니다. 그렇지 않으면 토토 사이트 순위 이후 명령문으로 전달됩니다.계속.

계속모두와 함께 사용할 수 있습니다. 토토 사이트 순위 유형; 무조건적으로 사용하도록 제한되지는 않습니다. 토토 사이트 순위.

예:

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

36.7.3.4. 동안

[ <<라벨 ]
하는 동안표현토토 사이트 순위문장END 토토 사이트 순위 [ 라벨 ];

동안문은 다음을 반복합니다. 조건 표현식이 포함된 일련의 명령문 사실로 평가됩니다. 조건은 각 직전에 확인됩니다. 토토 사이트 순위 본문에 진입합니다.

예:

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

boolean_expression LOOP가 아닌 동안
    -- 여기에 몇 가지 계산이 있습니다.
끝 토토 사이트 순위;

36.7.3.5. for(정수 변형)

[ <<라벨 ]
을 위한이름IN [반전] 표현 .. 표현토토 사이트 순위문장END 토토 사이트 순위 [ 라벨 ];

이 형태는for토토 사이트 순위를 생성합니다 이는 정수 값의 범위를 반복합니다. 변수이름자동으로 정의됩니다. 유형으로정수그리고 내부에만 존재합니다 토토 사이트 순위. 하한과 상한을 나타내는 두 가지 표현 범위의 경계는 토토 사이트 순위에 들어갈 때 한 번 평가됩니다. 반복 단계는 일반적으로 1이지만 다음과 같은 경우에는 -1입니다.반전지정되었습니다.

정수의 몇 가지 예for토토 사이트 순위:

i IN 1..10 토토 사이트 순위용
    -- 여기에 몇 가지 계산이 있습니다.
    인상 알림 'i는 %'입니다., i;
엔드 토토 사이트 순위;

역방향 10..1 토토 사이트 순위의 i용
    -- 여기에 몇 가지 계산이 있습니다.
끝 토토 사이트 순위;

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

36.7.4. 쿼리를 통한 루핑 결과

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

[ <<라벨 ]
을 위한record_or_rowIN질의토토 사이트 순위문장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;

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

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

[ <<라벨 ]
을 위한record_or_row실행 중텍스트 표현토토 사이트 순위문장END 토토 사이트 순위 [ 라벨 ];

이것은 소스를 제외하고 이전 양식과 같습니다선택문은 다음과 같이 지정됩니다. 각 항목에서 평가되고 다시 계획되는 문자열 표현식 에 입장for토토 사이트 순위. 이를 통해 프로그래머는 미리 계획된 쿼리의 속도를 선택하거나 일반 쿼리와 마찬가지로 동적 쿼리의 유연성실행진술.

참고:PL/pgSQL파서 현재 두 종류를 구별합니다.for다음 여부를 확인하여 토토 사이트 순위(정수 또는 쿼리 결과)..괄호 밖에 나타남 사이IN그리고토토 사이트 순위. 만약에..아님 그러면 토토 사이트 순위는 행에 대한 토토 사이트 순위인 것으로 추정됩니다. 잘못 입력함..그러므로 가능성이 높습니다 다음과 같은 불만 사항이 제기됩니다."행에 대한 토토 사이트 순위의 토토 사이트 순위 변수는 레코드여야 합니다. 또는 행 변수", 단순한 구문이 아닌 오류가 발생할 것으로 예상할 수 있습니다.

36.7.5. 트래핑 오류

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

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

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

조건이름은 다음과 같습니다. 다음 중 하나에 표시됨Postgre메이저 토토 사이트 : 문서 : 8.1 : 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하지만 의 효과업데이트명령은 롤백되었습니다. 그만큼삽입37644_37760톰 존스아님조 존스.

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

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

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