이 섹션과 다음 섹션에서는 모든 것을 설명합니다. 명시 적으로 이해되는 진술 유형pl/pgsql. 하나로 인식되지 않은 것 이 진술 유형은 SQL 명령으로 추정되며 에 설명 된대로 실행하려면 기본 데이터베이스 엔진으로 전송됩니다.섹션 38.5.2및섹션 38.5.3.
값의 할당pl/pgsql변수 또는 행/레코드 필드는입니다 as :
변수: =표현;
위에서 설명한 바와 같이, 그러한 진술의 표현은 다음과 같습니다. SQL을 통해 평가select기본 데이터베이스 엔진으로 전송 된 명령. 표현은해야합니다 단일 값을 산출하십시오.
표현식의 결과 데이터 유형이 일치하지 않으면 변수의 데이터 유형이거나 변수는 특정입니다 크기/정밀도 (예 :char (20)), 결과 값은에 의해 암시 적으로 변환됩니다.pl/pgsql결과를 사용한 통역사 유형의 출력 기능 및 변수 유형의 입력 기능. 이로 인해 런타임 오류가 발생할 수 있습니다 문자열 형태의 입력 함수에 의해 생성 된 결과 값은 입력 기능에 허용되지 않습니다.
예 :
세금 : = 하위 토탈 * 0.06; my_record.user_id : = 20;
예를 들어 행을 반환하지 않는 SQL 명령의 경우삽입a반환조항, 롤 토토을 실행할 수 있습니다 A 내에서pl/pgsql함수 롤 토토을 작성하면.
Anypl/pgsql변수 이름 명령 텍스트에 나타나는 것은 매개 변수로 대체됩니다. 기호, 그리고 변수의 현재 값이 제공됩니다. 실행 시간에 매개 변수 값으로 이것은 똑같습니다 표현에 대해 앞에서 설명한 처리; 자세한 내용은 참조섹션 38.10.1. 예를 들어, 글을 쓰면 :
선언 핵심 텍스트; 델타 정수; 시작하다 ... myTab set val = val + delta where id = key; 업데이트
기본 SQL 엔진에서 보이는 명령 텍스트가 보입니다. 좋다:
업데이트 MyTab Set Val = Val + $ 1 여기서 id = $ 2;
일반적으로 이것에 대해 생각할 필요는 없지만 구문 오류를 이해해야 할 때 알아두면 도움이됩니다. 메시지.
주의 |
pl/pgsql의지 중 하나와 일치하는 식별자를 대체하십시오 함수의 선언 된 변수; 충분히 밝지 않습니다 그것이 당신이 의미하는지 여부를 아는 것입니다! 따라서, 그것은입니다 어떤 것과 동일한 변수 이름을 사용하는 것이 나쁜 생각 필요한 테이블, 열 또는 기능 이름 함수 내 명령에서 참조. 자세한 내용 토론 참조섹션 38.10.1. |
이러한 방식으로 SQL 명령을 실행할 때pl/pgsql롤 토토을 한 번만 계획하십시오 후속 처형에 대한 계획을 재사용합니다. 데이터베이스 연결. 이것의 의미는 논의된다 세부 사항섹션 38.10.2.
때로는 표현 또는를 평가하는 것이 유용합니다select쿼리하지만 결과를 버리고, 예를 들어 부작용이있는 함수를 호출 할 때 유용한 결과 값이 없습니다.pl/pgsql, 사용공연진술 :
공연쿼리;
이것은 실행쿼리및 결과를 버립니다. 쓰기쿼리SQL을 작성하는 것과 같은 방식select롤 토토이지만 교체하십시오 초기 키워드selectwith공연. pl/pgsql변수가 대체됩니다 결과를 반환하지 않는 명령과 마찬가지로 쿼리로 계획은 같은 방식으로 캐시됩니다. 또한 특수 변수발견16122_16225섹션 38.5.5).
참고 :그 글쓰기를 기대할 수 있습니다select직접이를 달성 할 것입니다 결과이지만 현재로서는 유일한 수용 방법은입니다.공연. 할 수있는 SQL 명령 와 같은 반환 행select, Will 가없는 한 오류로 거부됩니다.in다음에 논의 된 절 부분.
예 :
create_mv ( 'cs_session_page_requests_mv', my_query); 수행
단일 행을 산출하는 SQL 명령의 결과 (아마도 여러 열의)) 레코드 변수에 할당 할 수 있습니다. 행 형 변수 또는 스칼라 변수 목록. 이것은 이에 의해 수행됩니다 기본 SQL 명령 작성 및 추가into절. 예를 들어,
selectselect_expressions[ 내엄격한]대상삽입 ... 반환표현[에엄격한]대상; 업데이트 ... 반환표현[에엄격한]대상; 삭제 ... 반환표현[에엄격한]대상;
여기서대상레코드가 될 수 있습니다 변수, 행 변수 또는 쉼표로 구분 된 간단한 목록 변수 및 레코드/행 필드.pl/pgsql변수가 대체됩니다 쿼리의 나머지 부분으로, 계획은 행을 반환하지 않는 명령에 대해 위에서 설명했습니다. 이것 Worksselect, 삽입/업데이트/삭제with반환및 유틸리티 명령 반환 행 설정 결과 (예 :설명). 을 제외하고in절에서 SQL 명령은 그것과 동일합니다 외부에 쓰여질 것입니다pl/pgsql.
팁 :이 해석에 주목하십시오.selectwithintois 와는 상당히 다릅니다PostgreSQL'S Regement선택명령, 여기서inTarget은 새로 생성 된 테이블입니다. 당신이 A에서 테이블을 만들고 싶습니다.select내부의 결과pl/pgsql함수, 구문 사용테이블 작성 ... 선택.
행 또는 가변 목록이 대상으로 사용되는 경우 쿼리의 결과 열은 대상의 구조와 정확히 일치해야합니다. 번호 및 데이터 유형 또는 런타임 오류가 발생합니다. 언제 a 레코드 변수는 대상이며 자동으로 구성됩니다 쿼리 결과 열의 행 유형에 자체.
thein절은 거의 나타날 수 있습니다 SQL 명령의 어느 곳에서나. 관습 적으로 그것은 쓰여졌습니다 직전 또는 바로 직전select_expressionsinselect롤 토토 또는 롤 토토의 끝에 다른 롤 토토 유형. 당신이 이것을 따르는 것이 좋습니다 대회의 경우pl/pgsql파서는 앞으로 더 엄격 해집니다 버전.
if엄격한에 지정되어 있지 않습니다.in조항,대상첫 번째 행으로 설정됩니다 쿼리로 반환하거나 쿼리가 반환 된 경우 Nulls로 반환 줄. ("첫 번째 줄"IS 사용하지 않는 한 잘 정의되지 않았습니다주문 에 의해.) 첫 번째 행 후 결과 행은 폐기됩니다. 스페셜을 확인할 수 있습니다발견변수 (참조섹션 38.5.5) 행이 반환되었는지 여부를 결정하려면 :
empname = myName에서 EMP에서 MyRec에 *를 선택하십시오. 찾을 수없는 경우 예외 '직원 % 찾을 수 없음', MyName; 끝 If;
엄격한옵션이 지정되어 있습니다. 쿼리는 정확히 하나의 행을 반환해야합니다. 그렇지 않으면 런타임 오류가 보고되면, 어느 쪽이든no_data_found(no 줄) 또는TOO_MANY_ROWS(하나 이상 열). 잡으려면 예외 블록을 사용할 수 있습니다. 예를 들면 오류 :
시작 Empname = myName에서 Emp에서 Strict Myrec으로 * 선택하십시오. 예외 그렇다면 no_data_found 일 때 예외 '직원 % 찾을 수 없음', MyName; 언제 너무 _many_rows 예외를 제기하는 '직원 % 고유하지 않음', MyName; 끝;
롤 토토의 성공적인 실행엄격한항상 설정발견to true.
for삽입/업데이트/삭제with반환, pl/pgsql그 이상에 대한 오류를보고합니다 반환 된 줄 하나,엄격한is 지정되지 않았습니다. 와 같은 옵션이 없기 때문입니다.주문 by영향을받는 행을 반환해야합니다.
참고 :the엄격한옵션 Oracle PL/SQL의 동작과 일치선택및 관련 진술.
여러 결과를 처리 해야하는 케이스를 처리하려면 SQL 쿼리의 행, 참조섹션 38.6.4.
종종 내부에 동적 롤 토토을 생성하고 싶을 것입니다 당신의pl/pgsql기능, 그 기능 다른 테이블이나 다른 롤 토토 데이터 유형이 실행 될 때마다.pl/pgsql의 정상적인 계획을 캐시하려는 시도 롤 토토 용 (섹션 38.10.2)는 그러한 시나리오에서 작동하지 않습니다. 이것을 처리합니다 일종의 문제,execute진술 제공됩니다 :
executeCommand-string[[ 내엄격한]대상 ];
여기서Command-stringis 문자열을 산출하는 표현 (유형텍스트) 실행 할 롤 토토을 포함하고대상레코드 변수입니다. 행 변수 또는 간단한 변수의 쉼표로 구분 된 목록 및 레코드/행 필드.
대체 없음pl/pgsql변수는 계산 된 명령 문자열에서 수행됩니다. 필요한 모든 변수 값은 명령 문자열에 삽입해야합니다. 건설.
또한,execute. 대신, 롤 토토은입니다 진술이 실행될 때마다 준비됩니다. 따라서 롤 토토 문자열은 함수 내에서 동적으로 생성 될 수 있습니다 다른 테이블과 열에서 동작을 수행합니다.
thein조항은 위치를 지정합니다 SQL 명령의 결과를 반환하는 행의 결과를 할당해야합니다. 만약에 행 또는 가변 목록이 제공되며 정확히 일치해야합니다. 쿼리 결과 구조 (레코드 변수가 중고, 결과 구조와 일치하도록 구성됩니다. 자동으로). 여러 행이 반환되면 첫 번째 행만이 반환됩니다 에 할당됩니다.in변수. 행이 반환되지 않으면 NULL이에 할당됩니다.in변수. 그렇지 않은 경우into조항이 지정되어 있으며 쿼리 결과가 있습니다 폐기.
엄격한옵션이 제공됩니다 쿼리가 정확히 하나를 생성하지 않는 한 오류 가보고됩니다 열.
선택현재는 없습니다 지원execute; 대신에, 평원 실행select롤 토토 및 지정in의 일부로execute자체.
참고 :thepl/pgsql execute진술은와 관련이 없습니다와이즈 토토 : 문서 : 8.3 : executeSQL 에 의해 뒷받침되는 진술PostgreSQL서버. 서버의execute롤 토토문을 사용할 수 없습니다 직접pl/pgsql기능 (필요하지 않음).
동적 명령으로 작업 할 때 종종 단일 따옴표의 탈출을 처리합니다. 권장 방법 기능 본문에서 고정 텍스트를 인용하는 것은 달러 인용입니다. (만약에 달러 인용문을 사용하지 않는 레거시 코드가 있습니다. 개요를 참조하십시오.섹션 38.11.1, 번역 할 때 약간의 노력을 절약 할 수 있습니다 더 합리적인 체계에 대한 코드.)
구성에 삽입 될 동적 값 쿼리는 스스로 할 수 있으므로 신중한 취급이 필요합니다 인용 문자를 포함합니다. 예제 (이것은 당신이 생각합니다 기능 전체에 대한 달러 인용 사용이므로 인용문 마크는 두 배가 될 필요가 없습니다) :
실행 'TBL 세트 업데이트' || quote_ident (colname) || '=' || quote_literal (newValue) || 'key =' || quote_literal (keyvalue);
이 예제는의 사용을 보여줍니다.QUOTE_INDEN
andquote_literal
함수. 안전을 위해
열 및 테이블 식별자를 포함하는 표현식이 있어야합니다
전달QUOTE_INDEN
.
문자 그대로 문자열이어야하는 값을 포함하는 표현
구성 명령은로 전달되어야합니다.QUOTE_LITERAL
. 둘 다 적절한 것을 취합니다
이중 또는 단일로 둘러싸인 입력 텍스트를 반환하는 단계
내장 된 특수 문자와 함께 각각 인용합니다
제대로 탈출.
달러 견적은 고정 인용에만 유용합니다. 텍스트. 위의 일을 시도하는 것은 매우 나쁜 생각입니다. 예제 :
실행 'TBL 세트 업데이트' || quote_ident (colname) || '= $$' || NewValue || '$$ key =' || quote_literal (keyvalue);
의 내용이 끊어지기 때문에NewValue함유$$. 같은 반대는 다른 반대에 적용됩니다
당신이 선택할 수있는 달러 인용 분리기. 따라서 안전하게 인용합니다
미리 알려지지 않은 텍스트, 당신은필수useQUOTE_LITERAL
.
동적 롤 토토의 훨씬 더 큰 예와execute예 38-6, a를 구축하고 실행합니다.생성 기능새 함수를 정의하는 롤 토토.
롤 토토의 효과를 결정하는 몇 가지 방법이 있습니다. 첫 번째 방법은를 사용하는 것입니다.진단롤 토토, 양식이 있습니다.
진단 받기변수=항목[ , ... ];
이 롤 토토은 시스템 상태 표시기를 검색 할 수 있습니다. 각항목는 핵심 단어입니다 지정된 상태에 할당 할 상태 값 식별 변수 (수신하기에 적합한 데이터 유형이어야합니다. 그것). 현재 사용 가능한 상태 항목은row_count, 마지막SQL롤 토토이 전송됩니다SQL엔진 및result_oid, 마지막 행의 OID 가장 최근에 삽입SQL롤 토토. 참고result_oid후에 만 유용합니다삽입OID를 포함하는 테이블에 롤 토토.
예 :
진단 받기 integer_var = row_count;
명령의 효과를 결정하는 두 번째 방법은 다음과 같습니다. 이름이 지정된 특수 변수를 확인하려면발견, 유형의부울. 발견시작합니다 각각의 거짓pl/pgsql함수 호출. 다음 유형의 각 유형에 의해 설정됩니다. 진술 :
a선택롤 토토문 세트발견행이 할당 된 경우 True 행이 반환되지 않으면 false.
a공연롤 토토문 세트발견그것이 생산하는 경우 (및 소실) 하나 이상의 행, 행이없는 경우 거짓 생산.
업데이트, 삽입및삭제진술 세트발견true if at 최소 한 행에 영향을 받고 행이 영향을받지 않으면 거짓입니다.
afetch롤 토토문 세트발견행을 반환하는 경우 True 행이 반환되지 않으면 false.
a움직임롤 토토문 세트발견성공적이면 참 커서를 재배치하고, 그렇지 않으면 거짓.
afor롤 토토문 세트발견한 번 이상 반복하면 True, 그렇지 않으면 거짓. 이것은의 세 가지 변형에 모두 적용됩니다.forStatement (Integerfor루프, 레코드 세트for루프 및 동적 레코드 세트for루프).발견이런 식으로 설정됩니다.for루프 출구; 루프 실행 내부에서발견for진술은 변경 될 수 있지만 루프 내 다른 진술의 실행에 의해 몸.
발견내면의 로컬 변수입니다 각PL/PGSQL함수; 어느 그것에 대한 변경은 현재 함수에만 영향을 미칩니다.
때때로 아무것도하지 않는 자리 표시 자 진술 유용한. 예를 들어, 하나의 팔이 /then/else 체인이 의도적으로 비어 있습니다. 이를 위해 사용하십시오 그만큼NULL진술 :
null;
예를 들어, 다음 두 조각의 코드는 다음과 같습니다 동등한:
시작 Y : = x / 0; 예외 Division_by_zero가있을 때 널; - 오류를 무시하십시오 끝;
시작 Y : = x / 0; 예외 Division_By_Zero 일 때 - 오류를 무시하십시오 끝;
바람직한 맛의 문제입니다.
참고 :Oracle의 PL/SQL에서 빈 명령문 목록 허용되지 않습니다.NULL진술은필수그러한 상황 이로.pl/pgsql허용 당신은 그냥 아무것도 쓰지 않고 대신.