제어 구조는 아마도 가장 유용하고 중요한 부분 일 것입니다pl/pgsql. 와 함께pl/pgsql의 제어 구조, 조작 할 수 있습니다postgresql매우 유연하고 강력한 방식으로 데이터.
함수에서 데이터를 반환 할 수있는 두 가지 명령이 있습니다.return
and다음 반환
.
return
#return표현
;
return
표현식과 함께 함수를 종료하고 값을 반환합니다표현
발신자에게. 이 양식은에 사용됩니다.pl/pgsql세트를 반환하지 않는 기능.
스칼라 유형을 반환하는 함수에서 표현식 결과는 할당에 대해 설명 된대로 기능의 반환 유형으로 자동으로 표시됩니다. 그러나 합성 (행) 값을 반환하려면 요청 된 열 세트를 정확히 전달하는 표현식을 작성해야합니다.
출력 매개 변수로 함수를 선언 한 경우 JUTEreturn
표현이없는. 출력 매개 변수의 현재 값이 반환됩니다.
반환으로 함수를 선언 한 경우void
, areturn
명령문은 기능을 조기에 종료하는 데 사용될 수 있습니다. 그러나 다음 표현을 작성하지 마십시오return
.
함수의 반환 값은 정의되지 않은 상태로 남을 수 없습니다. 제어가 A를 치지 않고 함수의 최상위 블록의 끝에 도달하는 경우return
문, 런타임 오류가 발생합니다. 이 제한은 출력 매개 변수 및 기능이 반환되는 함수에 적용되지 않습니다void
. 그러한 경우 areturn
최상위 블록이 완료되면 명령문이 자동으로 실행됩니다.
일부 예 :
- 스칼라 유형을 반환하는 기능
다음 반환
andreturn query
#다음 반환표현
;쿼리
;Command-string
[사용표현
[, ... ] ];
언제pl/pgsql함수는 반환으로 선언 됨setof
, 따라야 할 절차는 약간 다릅니다. 이 경우 반환 할 개별 항목은 시퀀스로 지정됩니다.Somegeype
다음 반환
또는return query
명령, 그리고 최종return
인수가없는 명령은 함수가 실행 된 것을 나타내는 데 사용됩니다.다음 반환
스칼라 및 복합 데이터 유형 모두에서 사용할 수 있습니다. 복합 결과 유형을 사용하여 전체“테이블”결과가 반환됩니다.return query
함수의 결과 세트에 쿼리를 실행 한 결과를 추가합니다.다음 반환
andreturn query
단일 설정 함수로 자유롭게 혼합 될 수 있으며,이 경우 결과가 연결됩니다.
다음 반환
andreturn query
실제로 함수에서 돌아 오지 마십시오. 단순히 함수의 결과 세트에 0 이상을 추가합니다. 그런 다음 실행은의 다음 진술로 계속됩니다.pl/pgsql함수. 연속다음 반환
또는return query
명령이 실행되고 결과 세트가 쌓입니다. 최종return
, 인수가 없어야하는 것은 제어가 함수를 종료하도록 유발합니다 (또는 제어가 함수의 끝에 도달하게 할 수 있습니다)..
return query
변형이 있습니다return query execute
는 동적으로 실행될 쿼리를 지정합니다. 매개 변수 표현식은를 통해 계산 된 쿼리 문자열에 삽입 할 수 있습니다.사용
,와 같은 방식으로execute
명령.
출력 매개 변수로 함수를 선언 한 경우 JUTE다음 반환
표현이없는. 각 실행에서 출력 매개 변수 변수의 현재 값은 결과 행으로 최종 반환을 위해 저장됩니다.Setof Record
여러 출력 매개 변수가있을 때 또는setof
유형의 출력 매개 변수가 하나만있을 때Somegeype
Somegeype
, 출력 매개 변수로 설정된 설정 함수를 만들려면
다음을 사용하는 함수의 예는입니다.다음 반환
:
테이블 foo (FOOD INT, FOOSUBID int, fooname 텍스트) 만들기;
다음을 사용하는 함수의 예는입니다.return query
:
함수 생성 get_available_flightid (날짜) 정수를 설정합니다
현재의 구현다음 반환
andreturn query
위에서 설명한대로 함수에서 돌아 오기 전에 전체 결과 세트를 저장합니다. 그것은 a이라는 것을 의미합니다.pl/pgsql함수는 매우 큰 결과 세트를 생성하고, 성능이 좋지 않을 수 있습니다 : 데이터는 메모리 소진을 피하기 위해 디스크에 기록되지만 전체 결과 세트가 생성 될 때까지 기능 자체가 반환되지 않습니다. 미래 버전의pl/pgsql사용자는이 제한이없는 설정 회복 함수를 정의 할 수 있습니다. 현재 데이터가 디스크에 기록되기 시작하는 지점은에 의해 제어됩니다.work_mem구성 변수. 메모리에 더 큰 결과 세트를 저장하기에 충분한 메모리를 가진 관리자는이 매개 변수를 증가시키는 것을 고려해야합니다.
프로 시저에는 리턴 값이 없습니다. 그러므로 절차는 a없이 끝날 수 있습니다.return
진술. a를 사용하려면return
코드를 일찍 종료하려는 명령문, JUTEreturn
표현이없는.
프로 시저에 출력 매개 변수가 있으면 출력 매개 변수의 최종 값이 발신자에게 반환됩니다.
A pl/pgsql함수, 절차 또는do
블록을 사용하여 절차를 호출 할 수 있습니다Call
. 출력 매개 변수는 방식과 다르게 처리됩니다.Call
일반 SQL에서 작동합니다. 각Out
또는inout
절차의 매개 변수는의 변수에 해당해야합니다.Call
명령문, 그리고 절차가 반환 된 후 해당 변수에 다시 할당됩니다. 예를 들어:
절차 생성 트리플 (inout x int)
출력 매개 변수에 해당하는 변수는 간단한 변수 또는 복합 유형 변수의 필드 일 수 있습니다. 현재 배열의 요소가 될 수 없습니다.
if
andCASE
진술은 특정 조건에 따라 대체 명령을 실행할 수 있습니다.pl/pgsql세 가지 형태의if
:
IF ... 그런 다음 ... IF
if ... then ... else ... end if
if ... 그런 다음 ... Elsif ... 그런 다음 ... End If
그리고 두 가지 형태의CASE
:
CASE ... 언제 ... 그런데 ... ELSE ... END CASE
케이스가 ... 그런 다음 ... else ... end case
if-then
#if부울-표현
the진술
END IF;
if-then
진술은 가장 간단한 형태의입니다.if
. 사이의 진술the
and종료 if
조건이 참이면 실행됩니다. 그렇지 않으면 건너 뜁니다.
예 :
if v_user_id <> 0입니다
if-then-else
#if부울-표현
the진술
else진술
END IF;
if-then-else
진술 추가if-then
조건이 사실이 아닌 경우 실행 해야하는 대체 명령문 세트를 지정할 수 있습니다. (여기에는 상태가 널로 평가되는 경우가 포함됩니다.)
예 :
Parentid가 null 또는 parentid = ''인 경우 = ''
V_count> 0이면
if-then-elsif
#if부울-표현
the진술
[elsif부울-표현
the진술
[elsif부울-표현
the진술
... ] ]else진술
]
때로는 두 가지 이상의 대안이 있습니다.if-then-elsif
차례로 몇 가지 대안을 확인하는 편리한 방법을 제공합니다. 그만큼if
조건은 참된 첫 번째 조건이 발견 될 때까지 연속적으로 테스트됩니다. 그런 다음 관련 진술이 실행되고 그 후 컨트롤이 다음 문으로 전달됩니다.종료 if
. (모든 후속if
조건은not테스트.)if
조건은 사실입니다.else
블록 (있는 경우)이 실행됩니다.
예는 다음과 같습니다.
if number = 0이면
키워드elsif
철자도elseif
.
동일한 작업을 수행하는 대안적인 방법은 둥지입니다if-then-else
다음 예와 같이 진술 :
demo_row.sex = 'm'이면
그러나이 방법은 일치하는 것을 작성해야합니다종료 if
각각if
, 사용하는 것보다 훨씬 번거 롭습니다elsif
많은 대안이있을 때.
CASE
#CASESearch-Expression
언제표현
[,표현
[ ... ]] 그런 다음진술
[언제표현
[,표현
[ ... ]] 그런 다음진술
... ]else진술
]
간단한 형태의CASE
피연산자의 평등에 따라 조건부 실행을 제공합니다. 그만큼Search-Expression
평가 (한 번)가 평가되고 각에 비해 연속적으로표현
in언제
조항. 일치가 발견되면 해당진술
실행 된 다음 컨트롤이 다음 명령문으로 전달됩니다최종 사례
. (후속언제
표현이 평가되지 않습니다.) 일치가 없으면else
진술
실행됩니다. 하지만 ifelse
존재하지 않으면 Acase_not_found
예외가 제기됩니다.
여기 간단한 예가 있습니다 :
케이스 x
CASE
#케이스부울-표현
the진술
[언제부울-표현
the진술
... ]else진술
]
검색 된 형태의CASE
부울 표현의 진실을 기반으로 조건부 실행을 제공합니다. 각언제
절부울-표현
수율이 발견 될 때까지 차례로 평가됩니다true
. 그러면 해당진술
실행 된 다음 컨트롤이 다음 명령문으로 전달됩니다최종 사례
. (후속언제
표현이 평가되지 않습니다.) 진정한 결과가 없으면else
진술
실행됩니다. 하지만 ifelse
존재하지 않으면 Acase_not_found
예외가 제기됩니다.
예는 다음과 같습니다.
케이스
이 형태의CASE
전적으로 동일합니다if-then-elsif
26479_26525else
조항은 아무것도하지 않고 오류가 발생합니다.
withloop
, 출구
, 계속
, while
, for
및foreach
진술, 당신은 당신의 것을 준비 할 수 있습니다pl/pgsql일련의 명령을 반복하는 기능.
loop
#[ <<레이블
]진술
엔드 토토 사이트 [레이블
];
loop
AN에 의해 종료 될 때까지 무기한 반복되는 무조건 토토 사이트를 정의합니다.출구
또는return
진술. 선택 사항레이블
출구
and계속
중첩 토토 사이트 내의 진술은 어떤 토토 사이트를 언급하는지.
출구
#출구 [레이블
] [언제부울-표현
];
그렇지 않은 경우레이블
주어지면, 가장 안쪽 토토 사이트가 종료되고 다음은 다음에엔드 토토 사이트
다음에 실행됩니다. 만약에레이블
주어지면 전류 또는 일부 외부 레벨의 중첩 토토 사이트 또는 블록의 레이블이어야합니다. 그런 다음 토토 사이트/블록의 해당 후 명명 된 토토 사이트 또는 블록이 종료되고 제어가 계속됩니다END
.
if언제
지정되어 있습니다. 토토 사이트 출구는 만 발생합니다.부울-표현
사실입니다. 그렇지 않으면 제어는 이후에 진술로 전달됩니다.출구
.
출구
모든 유형의 토토 사이트와 함께 사용할 수 있습니다. 무조건 토토 사이트와 함께 사용하는 것은 국한되지 않습니다.
a시작
블록,출구
블록 끝 이후 다음 명령문에 제어를 전달합니다. 이 목적으로 라벨을 사용해야합니다.출구
A와 일치하는 것으로 간주되지 않습니다시작
블록. (이것은 8.4 이전 릴리스에서의 변화입니다postgresql.출구
A와 일치하려면시작
블록.)
예 :
토토 사이트
계속
#계속 [레이블
] [언제부울-표현
];
그렇지 않은 경우레이블
가장 안쪽 토토 사이트의 다음 반복이 시작됩니다. 즉, 토토 사이트 본체에 남아있는 모든 진술은 건너 뜁니다. 다른 토토 사이트 반복이 필요한지 여부를 결정하기 위해 토토 사이트 제어 표현식 (있는 경우)으로의 제어 리턴이 반환됩니다.레이블
존재하고, 실행이 계속 될 토토 사이트의 레이블을 지정합니다.
if언제
지정되어 있습니다. 토토 사이트의 다음 반복은 만 시작됩니다.부울-표현
사실입니다. 그렇지 않으면 제어는 이후에 진술로 전달됩니다.계속
.
계속
모든 유형의 토토 사이트와 함께 사용할 수 있습니다. 무조건 토토 사이트와 함께 사용하는 것은 국한되지 않습니다.
예 :
토토 사이트
while
#[ <<레이블
]부울-표현
loop진술
엔드 토토 사이트 [레이블
];
thewhile
진술은만큼 일련의 진술을 반복합니다.부울-표현
true로 평가합니다. 표현식은 토토 사이트 본체에 각 입력 직전에 확인됩니다.
예 :
for
(정수 변형)#[ <<레이블
]이름
in [Reverse]표현
..표현
[by표현
] loop진술
엔드 토토 사이트 [레이블
];
이 형태의for
다양한 정수 값을 반복하는 토토 사이트를 만듭니다. 변수이름
자동으로 유형으로 정의정수
토토 사이트 내부에만 존재합니다 (변수 이름의 기존 정의는 토토 사이트 내에서 무시됩니다). 범위의 하부 및 상한을 제공하는 두 표현은 토토 사이트에 들어갈 때 한 번 평가됩니다.by
조항은 지정되지 않았습니다. 반복 단계는 1입니다. 그렇지 않으면에 지정된 값입니다.by
조항. 토토 사이트 항목에서 다시 한 번 평가됩니다. 만약에Reverse
지정된 다음 각 반복 후에 추가하지 않고 단계 값을 빼냅니다.
정수의 일부 예for
토토 사이트 :
1..10 토토 사이트의 i
하한이 상한보다 큰 경우 (또는Reverse
CASE), 토토 사이트 본체는 전혀 실행되지 않습니다. 오류가 발생하지 않습니다.
if a레이블
|for
토토 사이트 그러면 정수 토토 사이트 변수는 자격있는 이름으로 참조 할 수 있습니다.레이블
.
다른 유형의 사용for
토토 사이트, 쿼리 결과를 반복하고 그 데이터를 조작 할 수 있습니다. 구문은 다음과 같습니다.
[ <<레이블
]대상
in쿼리
loop진술
엔드 토토 사이트 [레이블
];
the대상
는 레코드 변수, 행 변수 또는 쉼표로 분리 된 스칼라 변수 목록입니다. 그만큼대상
|쿼리
각 행에 대해 토토 사이트 본체가 실행됩니다. 예는 다음과 같습니다.
함수 생성 refresh_mviews ()는 정수를 $$로 반환합니다
토토 사이트가 an에 의해 종료 된 경우출구
문서, 마지막으로 할당 된 행 값은 토토 사이트 후에도 여전히 액세스 할 수 있습니다.
the쿼리
이 유형에서 사용for
명령문은 발신자에게 행을 반환하는 SQL 명령이 될 수 있습니다 :select
가장 일반적인 경우이지만 사용할 수도 있습니다삽입
, 업데이트
, 삭제
또는병합
with반환
절. 와 같은 일부 유틸리티 명령설명
도 작동합니다.
pl/pgsql변수는 쿼리 매개 변수로 대체되며 쿼리 계획은 가능한 재사용을 위해 캐시됩니다.섹션 41.11.1and섹션 41.11.2.
thefor-in-execute
진술은 행을 반복하는 또 다른 방법입니다 :
[ <<레이블
]대상
executetext_expression
[사용표현
[, ... ] ] loop진술
엔드 토토 사이트 [레이블
];
이것은 소스 쿼리가 문자열 표현식으로 지정되며, 이는 각 항목에 대해 평가 및 대체 된 것을 제외하고는 이전 형식과 같습니다.for
토토 사이트. 이를 통해 프로그래머는 사전 계획된 쿼리의 속도 또는 일반 쿼리의 유연성을 선택할 수 있습니다.execute
진술. 와 마찬가지로execute
, 매개 변수 값을 동적 명령에 삽입 할 수 있습니다사용
.
결과를 반복 해야하는 쿼리를 지정하는 또 다른 방법은 커서로 선언하는 것입니다. 이것은에 설명되어 있습니다.섹션 41.7.4.
theforeach
토토 사이트는 A와 매우 흡사합니다for
토토 사이트이지만 SQL 쿼리로 반환 된 행을 반복하는 대신 배열 값의 요소를 통해 반복됩니다. (일반적으로foreach
| 복합 값 표현의 구성 요소를 통한 루핑을위한 것입니다. 배열 이외의 복합재를 통한 루핑의 변형은 향후에 추가 될 수 있습니다.)foreach
배열을 통해 토토 사이트를위한 명령문은 다음과 같습니다.
[ <<레이블
]대상
[슬라이스번호
] 배열표현
loop진술
엔드 토토 사이트 [레이블
];
없음슬라이스
또는 if슬라이스 0
지정되어 있으며, 토토 사이트는 평가하여 생성 된 배열의 개별 요소를 통해 반복됩니다표현
. 그만큼대상
변수는 각 요소 값이 순서대로 할당되며 각 요소에 대해 토토 사이트 본체가 실행됩니다. 다음은 정수 배열의 요소를 통한 루핑의 예입니다.
함수 SUM 작성 (int [])는 int8을 $$로 반환합니다
요소는 배열 치수 수에 관계없이 스토리지 순서로 방문됩니다. 비록대상
는 일반적으로 단일 변수 일 뿐이며 복합 값 (레코드) 배열을 통해 반복 할 때 변수 목록 일 수 있습니다. 이 경우 각 배열 요소에 대해 변수는 복합 값의 연속적인 열에서 할당됩니다.
긍정적 인슬라이스
value,foreach
단일 요소가 아닌 배열 조각을 통해 반복합니다. 그만큼슬라이스
값은 배열의 치수 수보다 더 큰 정수 일정이어야합니다. 그만큼대상
변수는 배열이어야하며 배열 값의 연속 슬라이스를 수신해야합니다. 여기서 각 슬라이스는에 의해 지정된 치수 수입니다.슬라이스
. 다음은 1 차원 슬라이스를 통한 반복의 예입니다.
함수 생성 Scan_rows (int [])는 void를 $$로 반환합니다
기본적으로 A에서 발생하는 오류pl/pgsql함수는 함수 및 주변 트랜잭션의 실행을 중단합니다. a를 사용하여 오류를 가두고 복구 할 수 있습니다.시작
예외
절. 구문은 a에 대한 일반 구문의 확장입니다.시작
블록 :
[ <<레이블
]선언선언
]진술
예외조건
[또는조건
... ] 그런 다음handler_statements
[언제조건
[또는조건
... ] 그런 다음handler_statements
... ]
오류가 발생하지 않으면이 형태의 블록은 단순히 모든 것을 실행합니다진술
END
. 그러나 내에서 오류가 발생하면진술
, 추가 처리진술
버려졌고 제어가로 통과합니다.예외
목록. 목록은 첫 번째를 검색합니다조건
발생한 오류와 일치합니다. 일치가 발견되면 해당handler_statements
실행 된 다음 컨트롤이 다음 명령문으로 전달됩니다END
. 일치가 발견되지 않으면 오류가 마치처럼 전파됩니다.예외
조항은 전혀 없었습니다.예외
또는 없으면 기능의 처리가 중단됩니다.
the조건
이름이 표시된 이름 일 수 있습니다PostgreSQL : 문서 : 17 : 부록 A. PostgreSQL 토토 꽁 머니 코드. 카테고리 이름은 해당 범주 내에서 오류와 일치합니다.기타
query_canceled
andAssert_Failure
. (이 두 가지 오류 유형을 이름별로 붙잡는 것은 가능하지만 종종 현명하지 않습니다.) 조건 이름은 대소 문자에 민감하지 않습니다.sqlstate
코드; 예를 들어, 이것들은 동일합니다 :
언제 division_by_zero가 ...
선택한 내에서 새 오류가 발생하면handler_statements
, 이에 따라 잡을 수 없습니다예외
조항이지만 전파됩니다. 주변예외
조항을 잡을 수 있습니다.
오류가 발생할 때예외
절의 조항,.pl/pgsql함수는 오류가 발생했을 때와 마찬가지로 유지되지만 블록 내 지속적인 데이터베이스 상태로의 모든 변경 사항이 롤백됩니다. 예를 들어이 조각을 고려하십시오 :
mytab에 삽입 (FirstName, lastName) 값 ( 'Tom', 'Jones');
제어가 할당에 도달하는 경우y
, A로 실패합니다.division_by_zero
오류. 이것은에 의해 잡힐 것입니다.예외
절. 반환 된 값return
명령문은 증분 값이 될 것입니다x
그러나의 효과업데이트
명령이 롤백됩니다. 그만큼삽입
앞의 명령은 롤백되지 않으므로 최종 결과에는 데이터베이스에 포함되어 있습니다.Tom Jones
notJoe Jones
.
an을 포함하는 블록예외
절은 하나가없는 블록보다 입력 및 종료하는 데 훨씬 비싸다. 따라서 사용하지 마십시오예외
필요없이.
예 41.2. 예외업데이트
/삽입
이 예제는 예외 처리를 사용하여 하나를 수행합니다업데이트
또는삽입
, 적절합니다. 응용 프로그램이 사용하는 것이 좋습니다삽입
with충돌시 업데이트
실제로이 패턴을 사용하지 않고. 이 예는 주로의 사용을 설명하는 역할을합니다.pl/pgsql제어 흐름 구조 :
테이블 DB 생성 (int 기본 키, b 텍스트);
이 코딩은를 가정합니다.고유 _violation
오류는에 의해 발생합니다.삽입
삽입
테이블의 트리거 함수에서. 테이블에 고유 한 인덱스가 둘 이상인 경우 오작동 할 수도 있습니다. 어떤 색인이 오류를 일으킨 지에 관계없이 작업을 재 시도하므로 오류가 발생할 수 있습니다.
예외 처리기는 발생한 특정 오류를 자주 식별해야합니다. 현재 예외에 대한 정보를 얻는 두 가지 방법이 있습니다.pl/pgsql: 특수 변수 및스택 진단 받기
명령.
예외 핸들러 내에서 특수 변수sqlstate
제기 된 예외에 해당하는 오류 코드가 포함되어 있습니다 (참조표 A.1가능한 오류 코드 목록의 경우). 특별 변수sqlerrm
예외와 관련된 오류 메시지를 포함합니다. 이 변수는 외부 예외 처리기 외부의 정의되지 않았습니다.
예외 핸들러 내에서를 사용하여 현재 예외에 대한 정보를 검색 할 수도 있습니다.스택 진단 받기
COMMAND : 양식이 있습니다.
스택 진단 받기가변
= | : =항목
[ , ... ];
각항목
지정된 상태 값을 식별하는 핵심 단어가변
(이를 수신하기에 적합한 데이터 유형이어야 함). 현재 사용 가능한 상태 항목은에 표시됩니다.표 41.2.
표 41.2. 오류 진단 항목
이름 | 타입 | 설명 |
---|---|---|
returned_sqlstate |
텍스트 |
예외의 SQLSTATE 오류 코드 |
column_name |
텍스트 |
예외와 관련된 열의 이름 |
제약 _name |
텍스트 |
예외와 관련된 제약 조건의 이름 |
PG_DATATYPE_NAME |
텍스트 |
예외와 관련된 데이터 유형의 이름 |
Message_Text |
텍스트 |
예외의 기본 메시지의 텍스트 |
table_name |
텍스트 |
예외와 관련된 테이블의 이름 |
Schema_Name |
텍스트 |
예외와 관련된 스키마의 이름 |
pg_exception_detail |
텍스트 |
예외 세부 메시지의 텍스트가있는 경우 |
pg_exception_hint |
텍스트 |
예외 힌트 메시지의 텍스트가 있다면 |
pg_exception_context |
텍스트 |
예외 당시 통화 스택을 설명하는 텍스트의 줄 (참조섹션 41.6.9) |
예외가 항목의 값을 설정하지 않으면 빈 문자열이 반환됩니다.
예는 다음과 같습니다.
선언
the진단 받기
명령, 이전에 설명 된섹션 41.5.5는 현재 실행 상태에 대한 정보를 검색합니다 (스택 진단 받기
위에서 논의한 명령은 이전 오류로 실행 상태에 대한 정보를보고합니다). 그것은PG_CONTEXT
상태 항목은 현재 실행 위치를 식별하는 데 유용합니다.PG_CONTEXT
통화 스택을 설명하는 텍스트의 줄이있는 텍스트 문자열을 반환합니다. 첫 번째 줄은 현재 함수와 현재 실행 중입니다진단 받기
명령. 두 번째 및 후속 선은 호출 함수를 통화 스택 위로 추가로 나타냅니다.
함수 생성 또는 교체 OUTER_FUNC () 정수를 $$로 반환합니다
스택 진단 받기 ... pg_exception_context
동일한 종류의 스택 추적을 반환하지만 현재 위치가 아닌 오류가 감지 된 위치를 설명합니다.
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다.이 양식문서 문제를보고하려면