스포츠 토토 9.3.25 문서화 | ||||
---|---|---|---|---|
PostgreSQL : 문서 : 9.3 : 토토 캔 문장 | Postgre메이저 토토 사이트 : 문서 : 9.3 : PL/PG메이저 토토 사이트 -메이저 토토 사이트 절차 언어 | 40 장pl/pgsql - SQL절차 언어 | 다음 |
스포츠 토토 구조는 아마도 가장 유용하고 중요합니다. 의 일부pl/pgsql. 와 함께pl/pgsql의 스포츠 토토 구조, 당신 조작 할 수 있습니다스포츠 토토데이터 in 매우 유연하고 강력한 방법.
데이터를 반환 할 수있는 두 가지 명령이 있습니다. 함수에서 :return및다음 반환.
return표현;
return표현식이 종료됩니다 함수와 값을 반환합니다표현발신자에게. 이 양식이 사용됩니다 을 위한pl/pgsql그렇지 않은 기능 세트를 반환하십시오.
스칼라 유형을 반환하는 함수에서 표현식 결과는 자동으로 기능의 반환 유형으로 캐스트됩니다. 과제에 대해 설명 된대로. 그러나 복합재를 반환하려면 (행) 가치, 당신은 정확히 전달하는 표현을 작성해야합니다 요청 된 열 세트. 이것은 명시적인 캐스팅을 사용해야 할 수 있습니다.
출력 매개 변수로 함수를 선언 한 경우 JUTEreturn표현이없는. 전류 출력 매개 변수 값이 반환됩니다.
반환으로 함수를 선언 한 경우void, areturn진술 할 수 있습니다 기능을 조기에 빠져 나가는 데 사용됩니다. 그러나 표현을 쓰지 마십시오 수행원return.
함수의 반환 값은 정의되지 않은 상태로 남을 수 없습니다. 만약에 스포츠 토토는 함수의 최상위 블록의 끝에 도달합니다. A를 때리지 않고return성명서, a 런타임 오류가 발생합니다. 이 제한은 적용되지 않습니다 출력 매개 변수 및 기능이있는 함수void. 그러한 경우 areturn명령문은 자동으로 실행됩니다 최상위 블록 마감.
일부 예 :
- 스칼라 유형을 반환하는 기능 반환 1 + 2; 반환 scalar_var; - 복합 유형을 반환하는 기능 return composite_type_var; return (1, 2, 'Three':: 텍스트); - 유형을 수정하기 위해 열을 캐스트해야합니다
다음 반환표현;
반환 쿼리쿼리;
반환 쿼리 executeCommand-string[사용표현[, ... ]];
언제pl/pgsql함수는입니다 반환으로 선언setofSOMENTYPE, 다음 절차는 IS입니다 약간 다릅니다. 이 경우 개별 항목이 돌아올 것입니다 시퀀스로 지정됩니다.다음 반환또는return query명령, 그리고 최종return인수가없는 명령이 사용됩니다 함수가 실행이 완료되었음을 나타냅니다.반환 다음스칼라와 함께 사용할 수 있습니다 복합 데이터 유형; 복합 결과 유형을 사용하여 전체"테이블"결과가 반환됩니다.return query결과를 추가합니다 함수의 결과 세트에 대한 쿼리 실행.반환 다음and반환 질문단일 세트 퇴행으로 자유롭게 혼합 될 수 있습니다 기능, 어떤 경우에는 결과가 연결됩니다.
다음 반환andreturn query실제로 돌아 오지 마십시오 기능 - 단순히 함수의 0 이상을 추가합니다. 결과 세트. 그런 다음 실행은의 다음 진술로 계속됩니다.pl/pgsql함수. 연속다음 반환또는반환 질문명령이 실행되고 결과 세트가 쌓입니다. 에이 결정적인return인수, 제어가 함수를 종료하게합니다 (또는 그냥 제어 기능의 끝에 도달).
return query변형이 있습니다return query execute15595_15726사용, in 와 마찬가지로execute명령.
출력 매개 변수로 함수를 선언 한 경우 JUTE다음 반환표현이없는. 각각에 실행, 출력 매개 변수 변수의 현재 값 결과의 행으로 최종 반환을 위해 저장됩니다. 주목하십시오 기능을 반환으로 선언해야합니다Setof Record여러 출력이있을 때 매개 변수 또는setofSOMENTYPE출력이 하나만있을 때 유형의 매개 변수약간의 Theype, in 출력으로 세트 리턴링 함수를 작성하려면 매개 변수.
여기를 사용하는 함수의 예는입니다.다음 반환:
테이블 foo (FOOD INT, FOOSUBID int, fooname 텍스트) 만들기; foo 값 (1, 2, 'Three')에 삽입; foo 값 (4, 5, 'Six')에 삽입; 함수를 만들거나 바꾸십시오 get_all_foo () foo setsof foo as를 반환합니다 $ body $ 선언하다 r foo%rowtype; 시작하다 r in을 위해 foo fool where food 0을 선택하십시오 고리 - 여기에서 약간의 처리를 할 수 있습니다 다음 r 반환; - 현재 선택의 현재 행을 반환합니다 엔드 스포츠 토토; 반품; 끝 $ body $ 언어 plpgsql; get_all_foo ();에서 *를 선택하십시오.
여기를 사용하는 함수의 예는입니다.return query:
함수 생성 get_available_flightid (날짜) 정수를 설정합니다 $ body $ 시작하다 쿼리를 반환합니다 비행에서 여기서 FlightDate = $ 1 및 FlightDate <($ 1 + 1); - 실행이 완료되지 않았으므로 행이 반환되었는지 확인할 수 있습니다. - 그렇지 않으면 예외를 제기하십시오. 찾을 수없는 경우 예외를 제기 ' %에서 비행 없음', $ 1; 끝 IF; 반품; 끝 $ body $ 언어 plpgsql; - 사용 가능한 항공편을 반환하거나 예외가없는 경우 - 사용 가능한 항공편. 선택 *에서 get_available_flightid (current_date);에서 선택하십시오.
참고 :현재의 구현다음 반환and반환 질문전체 결과 세트를 저장하기 전에 위에서 설명한대로 기능. 그것은 a이라는 것을 의미합니다.pl/pgsql함수는 매우 큰 결과를 생성합니다 세트, 성능이 좋지 않을 수 있습니다 : 데이터는 디스크로 기록됩니다. 메모리 피로를 피하면 기능 자체가 돌아 오지 않습니다. 전체 결과 세트가 생성 될 때까지. 미래 버전의pl/pgsql사용자가 허용 할 수 있습니다 이 제한이없는 설정 반복 함수를 정의하십시오. 현재 데이터가 디스크에 기록되기 시작하는 지점은 통제work_mem구성 변수. 메모리가 충분한 관리자 더 큰 결과 세트를 메모리에 저장하려면 증가하는 것을 고려해야합니다. 이 매개 변수.
ifandcase진술을 통해 특정 명령을 기준으로 대체 명령을 실행할 수 있습니다 정황.pl/pgsql3 개가 있습니다 의 형태if:
if ... then
if ... 그런 다음 ... else
if ... 그런 다음 ... Elsif ... 그런데 ... 또 다른
그리고 두 가지 형태의CASE:
CASE ... 언제 ... 그런데 ... ELSE ... END 사례
언제 ... 그런데 ... else ... 끝 사례
if부울-표현the진술END IF;
if-then진술이 가장 간단합니다 형태if. 사이의 진술theandEND IF조건이 참이면 실행됩니다. 그렇지 않으면, 그들은입니다 건너 뛰기.
예 :
if v_user_id < 0이면 사용자 업데이트는 이메일 = v_email user_id = v_user_id를 설정합니다. 끝 If;
if부울-표현the진술else진술종료 if;
if-then-else진술 추가if-then다음과 같은 경우 실행 해야하는 대체 진술 세트 조건은 사실이 아닙니다. (여기에는 경우가 포함됩니다 상태는 null로 평가합니다.)
예 :
Parentid가 null 또는 parentid = ''인 경우. 그 다음에 풀 이름을 반환하십시오. 또 다른 hp_true_filename (parentid) ||를 반환합니다 '/'|| 풀 이름; 끝 If;
V_count 0이면 user_count (count) 값 (v_count)에 삽입; 반환 't'; 또 다른 반환 'f'; 끝 If;
if부울-표현the진술[elsif부울-발현the진술[elsif부울-표현the진술 ...]] [else진술 ] 끝 If;
때로는 두 가지 이상의 대안이 있습니다.if-then-elsif편리한 방법을 제공합니다 차례로 몇 가지 대안을 확인합니다. 그만큼if조건은 다음까지 연속적으로 테스트됩니다 참된 첫 번째는 발견됩니다. 그런 다음 관련 진술 (들) 그 후 제어가 다음 명령문으로 전달되는 후에 실행됩니다. 후에종료 if. (모든 후속if조건은아님테스트.)if조건은 사실입니다.else블록 (있는 경우)이 실행됩니다.
여기 예입니다.
if number = 0이면 결과 : = 'Zero'; Elsif 번호 0 결과 : = '긍정적'; Elsif 번호 <0 결과 : = '부정'; 또 다른 - 흠, 유일한 다른 가능성은 숫자가 null이라는 것입니다. 결과 : = 'null'; 끝 If;
키워드elsif철자도elseif.
동일한 작업을 수행하는 대안적인 방법은 둥지입니다if-then-else진술 다음 예 :
demo_row.sex = 'm'이면 pretty_sex : = 'man'; 또 다른 demo_row.sex = 'f'라는 경우 pretty_sex : = '여자'; 끝 IF; 끝 If;
그러나이 방법은 일치하는 것을 작성해야합니다종료 if각각if사용하는 것보다 훨씬 더 번거 롭습니다elsif많은 대안이있을 때.
CASESearch-Expression언제표현[, 표현[ ... ]] 그런 다음진술[언제표현[, 표현[ ... ]] 그런 다음진술 ... ] [else진술 ] 최종 사례;
간단한 형태의CASE제공 피연산자의 평등을 기반으로 한 조건부 실행. 그만큼Search-Expression평가 (한 번) 및 각각에 비해표현in언제조항. 일치가 발견되면 동진술are 실행 된 다음 컨트롤이 다음 진술로 전달됩니다.최종 사례. (후속when표현이 평가되지 않습니다.) 일치가없는 경우 발견,else 진술실행됩니다. 하지만 ifelse존재하지 않으면 Acase_not_found예외가 제기됩니다.
여기 간단한 예가 있습니다 :
케이스 x 그때 1, 2 msg : = '하나 또는 둘'; 또 다른 MSG : = '하나 또는 두 이외의 기타 값'; 최종 사례;
케이스 언제부울-발현the진술[언제부울-표현the진술 ... ] [else진술 ] 최종 사례;
검색 된 형태의CASE제공 부울 표현의 진실을 기반으로 한 조건부 실행. 각언제절부울-표현차례로 평가되었습니다. 생산량이 발견 될 때까지true. 그 다음에 해당진술실행 된 다음 컨트롤이 다음 진술로 전달됩니다.최종 사례. (후속언제표현이 평가되지 않습니다.) 사실이 없다면 결과가 발견됩니다.else 진술실행됩니다. 하지만 ifelse존재하지 않으면 Acase_not_found예외가 제기됩니다.
여기 예입니다.
케이스 x가 0에서 10 사이에있을 때 msg : = '값은 0과 10 사이입니다. 11에서 20 사이의 x MSG : = '값은 11 ~ 20 사이입니다. 최종 사례;
이 형태의CASE는 전적으로입니다 동등한if-then-elsif를 제외하고 생략 된 규칙else조항은 아무것도하지 않고 오류가 발생합니다.
withloop, 출구, 계속, while, for및foreach진술, 당신은 당신의 것을 준비 할 수 있습니다pl/pgsql반복 할 기능 a 일련의 명령.
[ <<레이블 ] 고리진술엔드 스포츠 토토 [ 레이블 ];
loop무조건 스포츠 토토를 정의합니다 에 의해 종료 될 때까지 무기한 반복됩니다.출구또는return진술. 선택 사항레이블출구and계속중첩 스포츠 토토 내의 명령문은 스포츠 토토를 지정합니다 진술을 참조하십시오.
출구 [ 레이블 ] [언제부울-표현 ];
if no레이블가 제공됩니다 가장 안쪽 스포츠 토토가 종료되고 다음은 다음에엔드 스포츠 토토다음에 실행됩니다. 만약에레이블주어지면 라벨이어야합니다 중첩 스포츠 토토 또는 블록의 전류 또는 일부 외부 레벨. 그런 다음 지명 스포츠 토토 또는 블록이 종료되고 제어가 계속됩니다. 스포츠 토토/블록의 해당 이후의 명령문END.
if언제스포츠 토토 출구가 지정되어 있습니다 만 발생합니다.부울-표현사실입니다. 그렇지 않으면 제어는 이후에 진술로 전달됩니다.출구.
출구모든 유형과 함께 사용할 수 있습니다 스포츠 토토; 무조건 스포츠 토토와 함께 사용하는 것은 국한되지 않습니다.
a시작블록,출구다음 진술에 통제권을 전달합니다 블록의 끝 후. 이를 위해서는 레이블을 사용해야합니다 목적; 표지되지 않은출구절대 절대 A와 일치하는 것으로 간주시작블록. (이것 8.4 이전의 릴리스에서의 변화는입니다.PostgreSQL.출구A와 일치하려면시작블록.)
예 :
스포츠 토토 - 일부 계산 count 0이면 출구; - 종료 스포츠 토토 끝 IF; 엔드 스포츠 토토; 고리 - 일부 계산 count 0 일 때 종료; - 이전 예와 동일한 결과입니다 엔드 스포츠 토토; << ablock 시작하다 - 일부 계산 주식이 100000이면 자제 종료; - 시작 블록에서 종료됩니다 끝 IF; - 여기에 계산은 주식 100000시를 건너 뛸 것입니다. 끝;
계속 [ 레이블 ] [언제부울-표현 ];
NO레이블다음에 제공됩니다 가장 안쪽 스포츠 토토의 반복이 시작됩니다. 즉, 모든 진술입니다 스포츠 토토 본체에 남아있는 것이 건너 뜁니다. 다른 스포츠 토토 여부를 결정하기 위해 스포츠 토토 제어 표현식 (있는 경우) 반복이 필요합니다. 만약에레이블IS 현재, 그것은 실행이 될 스포츠 토토의 레이블을 지정합니다. 계속되는.
if언제지정되고 다음이 지정되어 있습니다 스포츠 토토 반복은에만 시작됩니다부울-표현사실입니다. 그렇지 않으면, 컨트롤은 이후에 진술로 전달됩니다.계속.
계속모든 유형과 함께 사용할 수 있습니다 스포츠 토토; 무조건 스포츠 토토와 함께 사용하는 것은 국한되지 않습니다.
예 :
스포츠 토토 - 일부 계산 카운트 100의 경우 종료; 카운트 <50을 계속하면 계속하십시오. - [50 .. 100]의 카운트 계산에 대한 일부 계산 엔드 스포츠 토토;
[ <<레이블 ] 하는 동안부울-표현스포츠 토토진술엔드 스포츠 토토 [ 레이블 ];
thewhile진술은 순서를 반복합니다 만큼 진술부울-표현true로 평가합니다. 그만큼 스포츠 토토 바디에 입력하기 직전에 표현이 점검됩니다.
예 :
while Voll_owed 0 및 Gift_certificate_balance 0 스포츠 토토 - 여기에 일부 계산 엔드 스포츠 토토; 스포츠 토토가 완료되지 않은 동안 - 여기에 일부 계산 엔드 스포츠 토토;
[ <<레이블 ] 을 위한이름in [Reverse]표현 .. 표현[by표현 ] loop진술엔드 스포츠 토토 [ 레이블 ];
이 형태의for스포츠 토토를 만듭니다 범위의 정수 값을 반복합니다. 변수이름자동으로 유형으로 정의정수스포츠 토토 내부에만 존재합니다 (Any 변수 이름의 기존 정의는 고리). 두 가지 표현은 스포츠 토토에 들어갈 때 범위가 한 번 평가됩니다. 인 경우by조항은 지정되지 않았습니다. 반복 단계는 1입니다. 그렇지 않으면 그것은에 지정된 값입니다.by절에서 다시 스포츠 토토에서 한 번 평가됩니다 기입. 만약에Reverse다음에 지정됩니다 각각 이후에 추가되지 않고 계단 값을 빼냅니다 반복.
정수의 일부 예for스포츠 토토 :
1.10 스포츠 토토의 i - 스포츠 토토 내에서 1,2,3,4,5,6,7,8,9,10 값을 취할 것입니다. 엔드 스포츠 토토; 반전 10..1 스포츠 토토 - 스포츠 토토 내에서 10,9,8,7,6,5,4,3,2,1 값을 취할 것입니다. 엔드 스포츠 토토; 반전 10..1 x 2 스포츠 토토 - 스포츠 토토 내에서 10,8,6,4,2 값을 맡을 것입니다. 엔드 스포츠 토토;
하한이 상한보다 큰 경우 에서ReverseCASE), 스포츠 토토 본체 전혀 실행되지 않습니다. 오류가 발생하지 않습니다.
if a레이블|for스포츠 토토 그런 다음 정수 스포츠 토토 변수 자격을 갖춘 이름으로 참조 할 수 있습니다.레이블.
다른 유형의 사용for스포츠 토토, 당신 쿼리 결과를 통해 반복하고 해당 데이터를 조작 할 수 있습니다. 따라서. 구문은 다음과 같습니다.
[ <<레이블 ] 을 위한대상in쿼리loop진술엔드 스포츠 토토 [ 레이블 ];
the대상레코드 변수입니다. 행 변수 또는 쉼표로 분리 된 스칼라 변수 목록. 그만큼대상연속적으로 할당되었습니다 에서 발생하는 각 행쿼리및 스포츠 토토 본체는 각 행에 실행됩니다. 예는 다음과 같습니다.
함수 생성 cs_refresh_mviews () 정수를 $$로 반환합니다 선언하다 mviews 레코드; 시작하다 '상쾌한 구체화 된 견해 ...'; SELECT *의 MVIEWS의 경우 CS_MATERIALIZED_VIEWS ORDER의 SORT_KEY LOOP 주문 - 이제 "mviews"는 cs_materialized_views의 한 레코드를 가지고 있습니다 '상쾌한 구체화 된보기 %s ...', quote_ident (mviews.mv_name); '잘린 테이블'||를 실행하십시오 quote_ident (mviews.mv_name); '삽입'실행 || quote_ident (mviews.mv_name) || '' '' || mviews.mv_query; 엔드 스포츠 토토; '상쾌한 구체화 된 견해를 수행했습니다.'; 반환 1; 끝; $$ 언어 plpgsql;
스포츠 토토가 an에 의해 종료 된 경우출구명령문, 마지막 지정된 행 값은 여전히 액세스 할 수 있습니다. 스포츠 토토.
the쿼리이 유형에서 사용forStatement는 SQL 명령이 될 수 있습니다 발신자에게 행을 반환합니다 :select입니다 가장 일반적인 경우이지만 사용할 수도 있습니다삽입, 업데이트, 또는삭제with반환절. 와 같은 일부 유틸리티 명령설명도 작동합니다.
pl/pgsql변수는입니다 쿼리 텍스트로 대체되며 쿼리 계획이 캐시됩니다. 자세히 논의 된 바와 같이.섹션 40.10.1and섹션 40.10.2.
thefor-in-execute진술은 또 다른 것입니다 오버 행을 반복하는 방법 :
[ <<레이블 ] 을 위한대상executetext_expression[사용표현[, ... ]] loop진술엔드 스포츠 토토 [ 레이블 ];
이것은 소스 쿼리가 평가 및 대체 된 문자열 표현식으로 지정 에 대한 각 항목에서for스포츠 토토. 이것은 허용합니다 미리 계획된 쿼리의 속도 또는 평범한 것과 마찬가지로 동적 쿼리의 유연성execute진술. 와 마찬가지로execute, 매개 변수 값을 삽입 할 수 있습니다 동적 명령을 통해사용.
결과가 필요한 쿼리를 지정하는 또 다른 방법 반복은 커서로 선언하는 것입니다. 이것은에 설명되어 있습니다.섹션 40.7.4.
theforeach스포츠 토토는 A와 매우 흡사합니다for스포츠 토토이지만 반복하는 대신 SQL 쿼리에 의해 반환 된 행은 요소를 통해 반복됩니다. 배열 값의. (일반적으로foreachIS 복합 값의 구성 요소를 통해 반복을 의미합니다 표현; 배열 이외의 복합재를 통한 루핑의 변형 미래에 추가 될 수 있습니다.)foreach배열을 통해 스포츠 토토를위한 명령문은 다음과 같습니다.
[ <<레이블 ] foreach대상[슬라이스번호 ] 배열표현스포츠 토토진술엔드 스포츠 토토 [ 레이블 ];
없음슬라이스또는 if슬라이스 0지정되어 스포츠 토토가 반복됩니다 평가하여 생성 된 배열의 개별 요소표현. 그만큼대상변수는 각 요소가 할당됩니다 순서대로 값과 스포츠 토토 본체가 각 요소에 대해 실행됩니다. 다음은 정수의 요소를 통한 루핑의 예입니다. 정렬:
함수 SUM 작성 (int [])는 int8을 $$로 반환합니다 선언하다 s int8 : = 0; x int; 시작하다 배열 $ 1의 Foreach X 고리 S : = S + X; 엔드 스포츠 토토; 반환 s; 끝; $$ 언어 plpgsql;
요소는 스토리지 순서로 방문합니다. 배열 치수 수. 비록대상는 일반적으로 단일 변수 일뿐입니다 배열을 통해 반복 할 때 변수 목록이 될 수 있습니다. 복합 값 (레코드). 이 경우 각 배열 요소에 대해 변수는 합성의 연속적인 열에서 할당됩니다. 값.
긍정적 인슬라이스value,foreach배열 조각을 통해 반복합니다 단일 요소보다. 그만큼슬라이스값은 필수입니다 차원 수보다 크지 않은 정수 상수 배열. 그만큼대상변수 배열이되고 배열 값의 연속 조각을 받고, 각 슬라이스는에 의해 지정된 치수 수입니다.슬라이스. 반복의 예는 다음과 같습니다 1 차원 슬라이스를 통해 :
함수 만들기 scan_rows (int [])는 void를 $$로 반환합니다 선언하다 x int []; 시작하다 배열 $ 1의 Foreach X Slice 1 고리 통지 '행 = %', x; 엔드 스포츠 토토; 끝; $$ 언어 plpgsql; Select Scan_rows (배열 [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]); 통지 : Row = 1,2,3
기본적으로 A에서 발생하는 오류가 발생합니다.pl/pgsql함수는 실행을 중단합니다 기능 및 실제로 주변 거래의 기능. 너 A를 사용하여 오류를 가두고 복구 할 수 있습니다.시작예외절. 구문은 연장입니다 A에 대한 일반 구문시작블록 :
[ <<레이블 ] [선언선언 ] 시작하다진술예외 언제조건[또는조건 ... ] 그런 다음handler_statements[언제조건[또는조건 ... ] 그런 다음handler_statements ... ] 끝;
오류가 발생하지 않으면이 형태의 블록은 모든 것을 실행합니다진술그리고 제어 패스 다음 진술 후에END. 그러나 만약 오류가 내에서 발생합니다.진술, 추가 처리진술버려지고 통제가 통과됩니다예외목록. 목록은입니다 첫 번째 검색조건발생한 오류 일치. 일치가 발견되면 동handler_statements실행 된 다음 다음 문의 다음 명령문으로 통제됩니다END. 일치하지 않으면 오류가 발생합니다 마치 마치 전파예외조항은 전혀 없었습니다. 오류는 블록을 둘러싸는예외또는 IF 기능의 처리를 중단하는 것은 없습니다.
the조건이름은 그럴 수 있습니다윈 토토 : 문서 : 9.3 : 윈 토토 윈 토토 코드. 카테고리 이름은 해당 범주 내에서 오류와 일치합니다. 스페셜 조건 이름기타모든 오류와 일치합니다 유형을 제외하고query_canceled. (그것은 가능하지만 종종 현명하지 않은 경우query_canceled이름으로) 조건 이름은 아닙니다 사례에 민감합니다. 또한 오류 조건은에 의해 지정할 수 있습니다.SQLSTATE코드; 예를 들어 이것들입니다 동등한:
say division_by_zero 당시 ... sqlstate '22012'때 ...
선택한 내에서 새 오류가 발생하는 경우handler_statements, 잡을 수 없습니다 이것예외조항이지만 전파됩니다 밖으로. 주변예외조항 잡아라.
오류가 AN에 의해 잡히면예외절,의 로컬 변수pl/pgsql함수는 그와 같이 남아 있습니다 오류가 발생했지만 내부의 지속적인 데이터베이스 상태에 대한 모든 변경 사항 블록이 롤백됩니다. 예를 들어, 이것을 고려하십시오 파편:
mytab에 삽입 (FirstName, lastName) 값 ( 'Tom', 'Jones'); 시작하다 mytab set firstName = 'joe'여기서 lastName = 'Jones'; x : = x + 1; Y : = x / 0; 예외 Division_by_zero가있을 때 'Caught Division_by_Zero'를 통지하십시오. 반환 x; 끝;
스포츠 토토가 할당에 도달 할 때y, A로 실패합니다.division_by_zero오류. 이것은에 의해 잡힐 것입니다.예외절. 반환 된 값 그만큼return진술은 다음과 같습니다 의 증분x그만큼업데이트명령이 롤링됩니다 뒤쪽에. 그만큼삽입이전의 명령 그러나 블록은 롤백되지 않으므로 최종 결과는 데이터베이스가 포함Tom JonesnotJoe Jones.
팁 :an을 포함하는 블록예외절은 훨씬 더 비쌉니다 블록이없는 블록보다 입력하고 나가십시오. 따라서 사용하지 마십시오예외필요없이.
예 40-2. 예외업데이트/삽입
이 예제는 예외 처리를 사용하여 하나를 수행합니다업데이트또는삽입, 적절하게 :
테이블 DB 생성 (int 기본 키, b 텍스트); 함수 생성 merge_db (key int, data text)는 void를 반환합니다 $$ 시작하다 고리 - 먼저 키를 업데이트하십시오 DB SET B = 데이터를 업데이트합니다. 여기서 a = 키; 그럼 발견된다면 반품; 끝 IF; - 거기에 있지 않으므로 키를 삽입하십시오 - 다른 사람이 동시에 같은 키를 동시에 삽입하면 -우리는 독특한 키 실패를 얻을 수 있습니다 시작하다 db (a, b) 값 (키, 데이터)에 삽입; 반품; 그때 고유 한 예외 - 아무것도하지 않고 업데이트를 다시 시도하려면 스포츠 토토하십시오. 끝; 엔드 스포츠 토토; 끝; $$ 언어 plpgsql; merge_db (1, 'david')를 선택하십시오. merge_db (1, 'dennis')를 선택하십시오.
이 코딩은를 가정합니다.고유 _violation오류는에 의해 발생합니다.삽입삽입테이블의 트리거 함수에서. 아마도 또한 테이블에 고유 한 인덱스가 둘 이상인 경우 잘못 행동하고 어떤 색인이 발생했는지에 관계없이 작업을 재 시도하기 때문에 오류. 논의 된 기능을 사용하여 더 많은 안전을 가질 수 있습니다. 갇힌 오류가 예상되었는지 확인하는 것입니다.
예외 핸들러는 종종 특정 사항을 식별해야합니다 발생한 오류. 정보를 얻는 방법에는 두 가지가 있습니다 현재 예외pl/pgsql: 특수 변수 및쌓아 올리십시오 진단명령.
예외 핸들러 내에서 특수 변수SQLSTATE해당 오류 코드를 포함합니다 제기 된 예외 (참조표 A-1목록 가능한 오류 코드). 특별 변수sqlerrm관련 오류 메시지가 포함되어 있습니다 예외. 이러한 변수는 외부 예외를 정의하지 않았습니다 핸들러.
예외 핸들러 내에서 정보를 검색 할 수도 있습니다 를 사용하여 현재 예외에 대해쌓인 진단명령, 양식이 있습니다.
스택 진단 받기가변=항목[ , ... ];
각항목는 핵심 단어입니다 지정된 변수에 할당 할 상태 값 식별 (이를 수신하기에 적합한 데이터 유형이어야합니다). 그만큼 현재 사용 가능한 상태 항목은에 표시됩니다.표 40-1.
표 40-1. 오류 진단 값
이름 | 타입 | 설명 |
---|---|---|
returned_sqlstate | 텍스트 | 예외의 sqlstate 오류 코드 |
column_name | 텍스트 | 예외와 관련된 열의 이름 |
제약 _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 텍스트; 시작하다 - 예외가 발생할 수있는 일부 처리 ... 다른 사람들이 예외 스택 진단 받기 텍스트 _var1 = message_text, text_var2 = pg_exception_detail, text_var3 = pg_exception_hint; 끝;