Postgresql 9.2.24 문서 | ||||
---|---|---|---|---|
토토 커뮤니티 : 문서 : 9.2 : 표현식 | up | 제 39 장pl/pgsql - SQL절차 언어 | 다음 |
이 섹션과 다음 섹션에서는 모든 것을 설명합니다. 명시 적으로 이해되는 진술 유형pl/pgsql. 하나로 인식되지 않은 것 이 진술 유형은 SQL 명령으로 추정되며 에 설명 된대로 실행하려면 기본 데이터베이스 엔진으로 전송됩니다.섹션 39.5.2and섹션 39.5.3.
값의 할당pl/pgsql변수는 다음과 같이 작성되었습니다.
가변: =표현;
앞에서 설명한 바와 같이, 그러한 진술의 표현 SQL을 통해 평가됩니다select기본 데이터베이스 엔진으로 전송 된 명령. 표현은해야합니다 단일 값을 산출합니다 (변수가있는 경우 행 값일 수 있습니다. 행 또는 레코드 변수). 대상 변수는 간단 할 수 있습니다 변수 (선택적으로 블록 이름으로 자격이 있음), 필드 행 또는 레코드 변수 또는 배열 요소 간단한 변수 또는 필드
표현식의 결과 데이터 유형이 일치하지 않으면 변수의 데이터 유형이거나 변수는 특정입니다 크기/정밀도 (예 :char (20)), 결과 값은에 의해 암시 적으로 변환됩니다.pl/pgsql결과를 사용한 통역사 유형의 출력 기능 및 변수 유형의 입력 기능. 이로 인해 런타임 오류가 발생할 수 있습니다 문자열 형태의 입력 함수에 의해 생성 된 결과 값은 입력 기능에 허용되지 않습니다.
예 :
세금 : = 하위 토탈 * 0.06; my_record.user_id : = 20;
예를 들어 행을 반환하지 않는 SQL 명령의 경우삽입a반환조항, 스포츠 토토 결과을 실행할 수 있습니다 A 내에서pl/pgsql함수 스포츠 토토 결과을 작성하면.
anypl/pgsql변수 이름 명령 텍스트에 나타나는 것은 매개 변수로 취급되고 그런 다음 변수의 현재 값이 실행 시간에 매개 변수 값. 이것은 똑같습니다 표현에 대해 앞에서 설명한 처리; 자세한 내용은 참조섹션 39.10.1.
이러한 방식으로 SQL 명령을 실행할 때pl/pgsql캐시하고 재사용 할 수 있습니다 스포츠 토토 결과에 대한 실행 계획에서 논의 된대로섹션 39.10.2.
때로는 표현식 또는를 평가하는 것이 유용합니다.select쿼리하지만 결과를 버리고, 예를 들어 부작용이있는 함수를 호출 할 때 유용한 결과 값이 없습니다.pl/pgsql, 사용공연진술 :
공연쿼리;
이것은 실행쿼리및 결과를 버립니다. 쓰기쿼리SQL을 작성하는 것과 같은 방식select스포츠 토토 결과이지만 교체하십시오 초기 키워드selectwith공연. 을 위한with쿼리, 사용공연그런 다음 배치하십시오 괄호 안의 쿼리. (이 경우 쿼리 만 가능합니다 한 줄 반환.)pl/pgsql변수는 쿼리로 대체됩니다. 결과를 반환하지 않는 명령은 같은 방식. 또한 특수 변수발견15093_15192섹션 39.5.5).
참고 :글쓰기를 기대할 수 있습니다select직접이를 달성 할 것입니다 결과이지만 현재로서는 유일한 수용 방법은입니다.공연. 할 수있는 SQL 명령 와 같은 반환 행select, Will 가없는 한 오류로 거부됩니다.into다음에 논의 된 절 부분.
예 :
create_mv 수행 ( 'cs_session_page_requests_mv', my_query);
단일 행을 산출하는 SQL 명령의 결과 (아마도 여러 열의)) 레코드 변수에 할당 할 수 있습니다. 행 형 변수 또는 스칼라 변수 목록. 이것은 이에 의해 수행됩니다 기본 SQL 명령 작성 및 추가in절. 예를 들어,
selectselect_expressions[에엄격한]대상삽입 ... 반환표현[에엄격한]대상; 업데이트 ... 반환표현[에엄격한]대상; 삭제 ... 반환표현[에엄격한]대상;
여기서대상레코드가 될 수 있습니다 변수, 행 변수 또는 쉼표로 구분 된 간단한 목록 변수 및 레코드/행 필드.pl/pgsql변수가 대체됩니다 쿼리의 나머지 부분으로, 계획은 행을 반환하지 않는 명령에 대해 위에서 설명했습니다. 이것 Worksselect, 삽입/업데이트/삭제with반환및 유틸리티 명령 반환 행 설정 결과 (예 :설명). 을 제외하고in절, SQL 명령은 그것과 동일합니다 외부에 쓰여질 것입니다pl/pgsql.
팁 :이 해석에 대한 주목selectwithinis 와는 상당히 다릅니다postgresql's Regular선택명령, 여기서in대상은 새로 생성 된 테이블입니다. 당신이 A에서 테이블을 만들고 싶습니다.select내부의 결과pl/pgsql함수, 구문 사용테이블 작성 ... 선택.
행 또는 가변 목록이 대상으로 사용되는 경우 쿼리 결과 열은 대상의 구조와 정확히 일치해야합니다. 번호 및 데이터 유형에 관해서는 런타임 오류가 발생합니다. 레코드 변수가 대상이되면 자동으로 쿼리 결과의 행 유형에 자체 구성 열.
theinto조항이 거의 나타날 수 있습니다 SQL 명령의 어느 곳에서나. 관습 적으로 그것은 쓰여졌습니다 직전 또는 바로 직전select_expressionsatselect스포츠 토토 결과 또는 스포츠 토토 결과의 끝에 다른 스포츠 토토 결과 유형. 당신이 이것을 따르는 것이 좋습니다 대회의 경우pl/pgsql파서는 앞으로 더 엄격 해집니다 버전.
if엄격한에 지정되어 있지 않습니다.in조항,대상첫 번째 행으로 설정됩니다 쿼리로 반환하거나 쿼리가 반환 된 경우 Nulls로 반환 줄. ("첫 번째 줄"is 사용하지 않는 한 잘 정의되지 않았습니다주문 에 의해.) 첫 번째 행 후 결과 행은 폐기됩니다. 스페셜을 확인할 수 있습니다발견변수 (참조섹션 39.5.5) 행이 반환되었는지 여부를 결정하려면 :
empname = myName; 찾을 수없는 경우 예외 '직원 % 찾을 수 없음', MyName; 끝 If;
if the엄격한옵션이 지정되어 있습니다. 쿼리는 정확히 하나의 행을 반환해야합니다. 그렇지 않으면 런타임 오류가 보고되면, 어느 쪽이든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 쿼리의 행, 참조섹션 39.6.4.
종종 내부에서 동적 스포츠 토토 결과을 생성하고 싶을 것입니다 당신의pl/pgsql기능, 그 기능 다른 테이블이나 다른 스포츠 토토 결과 데이터 유형이 실행 될 때마다.pl/pgsql의 정상적인 계획을 캐시하려는 시도 스포츠 토토 결과 용 (섹션 39.10.2)는 그러한 시나리오에서 작동하지 않습니다. 이것을 처리합니다 일종의 문제,execute진술 제공됩니다 :
executeCommand-string[[에엄격한]대상 ] [사용표현[, ... ]];
여기서Command-stringis 문자열을 산출하는 표현 (유형텍스트) 실행 할 명령을 포함합니다. 그만큼 선택 과목대상는 기록입니다 변수, 행 변수 또는 쉼표로 구분 된 간단한 목록 변수 및 레코드/행 필드. 명령이 저장됩니다. 선택 사항사용삽입 할 공급 값 명령에.
대체 없음PL/PGSQL변수는 계산 된 명령 문자열에서 수행됩니다. 필요한 모든 변수 값은 명령 문자열에 삽입해야합니다. 건설; 또는 아래에 설명 된대로 매개 변수를 사용할 수 있습니다.
또한,execute. 대신, 스포츠 토토 결과은입니다 명세서가 실행될 때마다 항상 계획됩니다. 따라서 스포츠 토토 결과 문자열은 함수 내에서 동적으로 생성 될 수 있습니다 다른 테이블과 열에서 동작을 수행합니다.
thein조항은 위치를 지정합니다 SQL 명령의 결과를 반환하는 행의 결과를 할당해야합니다. 만약에 행 또는 가변 목록이 제공되며 정확히 일치해야합니다. 쿼리 결과 구조 (레코드 변수가 중고, 결과 구조와 일치하도록 구성됩니다. 자동으로). 여러 행이 반환되면 첫 번째 행만이 반환됩니다 에 할당됩니다.in변수. 행이 반환되지 않으면 NULL이에 할당됩니다.in변수. 그렇지 않은 경우into조항이 지정되어 있으며 쿼리 결과가 있습니다 폐기.
엄격한옵션이 제공됩니다 쿼리가 정확히 하나를 생성하지 않는 한 오류 가보고됩니다 열.
명령 문자열은 매개 변수 값을 사용할 수 있습니다 명령에서에 참조$ 1, $ 2등.이 기호는 값을 나타냅니다 에 제공됨사용절. 이것 방법은 종종 데이터 값을 텍스트로 명령 문자열 : 런타임 오버 헤드를 피합니다 값을 텍스트와 뒤로 변환하면 훨씬 적습니다. 필요하지 않기 때문에 SQL 주입 공격이 발생하기 쉽습니다. 인용 또는 탈출. 예는 다음과 같습니다.
execute 'inserted_by = $ 1이고 삽입 된 mytable에서 count (*)를 선택하십시오 <= $ 2' c Checked_user 사용, Checked_date;
매개 변수 기호는 데이터 값에만 사용할 수 있습니다. - 동적으로 결정된 테이블 또는 열을 사용하려면 이름, 명령 문자열에 텍스트로 삽입해야합니다. 예를 들어, 이전 쿼리를 동적으로 선택된 테이블, 당신은 이것을 할 수 있습니다 :
execute 'count (*)에서' || tabname :: regclass || 'inserted_by = $ 1이고 삽입 된 <= $ 2' c Checked_user 사용, Checked_date;
매개 변수 기호에 대한 또 다른 제한은 그것들만이라는 것입니다 에서 일select, 삽입, 업데이트및삭제명령. 다른 진술에서 유형 (일반적으로 유틸리티 명령문이라고 함)은 삽입해야합니다 데이터 값에 불과하더라도 텍스트로 값.
anexecute단순한 상수 스포츠 토토 결과 문자열 및 일부사용위의 첫 번째 예에서와 같이 매개 변수는 기능적입니다 스포츠 토토 결과을 직접 작성하는 것과 동일합니다pl/pgsql및 교체 허용pl/pgsql변수가 발생합니다 자동으로. 중요한 차이점은execute각각에 대한 스포츠 토토 결과을 다시 계획합니다 실행, 현재와 관련된 계획 생성 매개 변수 값; 반면pl/pgsql그렇지 않으면 제네릭을 생성 할 수 있습니다 재사용을 위해 계획하고 캐시하십시오. 최고의 계획 인 상황에서 매개 변수 값에 크게 의존하면 도움이 될 수 있습니다. 사용execute긍정적으로 보장합니다 일반 계획은 선택되지 않았습니다.
선택현재는 없습니다 지원execute; 대신에, 평원 실행select스포츠 토토 결과 및 지정into의 일부로execute자체.
참고 :thepl/pgsql execute진술은와 관련이 없습니다토토 캔 : 문서 : 9.2 : executeSQL 문 지원PostgreSQL서버. 서버의execute명령문을 사용할 수 없습니다 직접pl/pgsql기능 (그리고 필요하지 않음).
예 39-1. 동적으로 값을 인용합니다 쿼리
동적 명령으로 작업 할 때 종종 단일 따옴표의 탈출을 처리합니다. 권장 방법 기능 본문에서 고정 텍스트를 인용하는 것은 달러 인용입니다. (달러 인용문을 사용하지 않는 레거시 코드가있는 경우 개요를 참조하십시오섹션 39.11.1, 번역 할 때 약간의 노력을 절약 할 수 있습니다 더 합리적인 체계에 대한 코드.)
동적 값을 삽입해야합니다 구성된 쿼리는 신중한 처리가 필요합니다 자체에는 인용 문자가 포함되어 있습니다. 예제 (이것은 가정합니다 당신이 기능을 위해 달러 인용문을 사용하고 있다는 전체, 따라서 견적 마크를 두 배로 늘릴 필요는 없습니다) :
실행 'TBL 세트 업데이트' || quote_ident (colname) || '=' || quote_literal (newValue) || 'key =' || quote_literal (keyvalue);
이 예제는의 사용을 보여줍니다.QUOTE_INDEN
andQUOTE_LITERAL
기능 (참조섹션 9.4). 안전을 위해
열 또는 테이블 식별자를 포함하는 표현식이 있어야합니다
통과QUOTE_INDEN
동적 쿼리에 삽입하기 전에. 포함 된 표현
구성된 문자열이어야하는 값
명령을 통과해야합니다quote_literal
. 이러한 기능은
두 배로 동봉 된 입력 텍스트를 반환하기위한 적절한 단계
또는 모든 내장 된 특별한 인용문
캐릭터가 제대로 탈출했습니다.
왜냐하면QUOTE_LITERAL
IS
레이블엄격한, 항상
Null 인수로 호출되면 Null을 반환하십시오. 위에서
예, ifNewValue또는KeyValue전체 동적 쿼리 인 null이었다
문자열은 무효가되어의 오류로 이어집니다.execute. 사용 하여이 문제를 피할 수 있습니다
그만큼QUOTE_NULLABLE
함수,
와 동일하게 작동합니다.quote_literal
31146_31222NULL. 예를 들어,
실행 'TBL 세트 업데이트' || quote_ident (colname) || '=' || quote_nullable (newValue) || 'key =' || quote_nullable (keyvalue);
NULL 일 수있는 값을 다루는 경우
일반적으로 사용해야QUOTE_NULLABLE
대신quote_literal
.
항상 그렇듯이 널 값을 보장하기 위해주의를 기울여야합니다. 쿼리에서는 의도하지 않은 결과를 제공하지 않습니다. 예를 들어여기서절
'여기서 key ='|| quote_nullable (keyvalue)
if 성공하지 못할 것입니다.KeyValueIS 평등 연산자 사용의 결과이기 때문에 NULL=null 피연산자가있는 것은 항상입니다 널. NULL이 일반적인 키 가치처럼 일하기를 원한다면 위를 다시 작성해야합니다.
'키가'||와 구별되지 않는 경우 quote_nullable (keyvalue)
(현재,||=, 그렇지 않으면 그렇게하지 마십시오. 보다PostgreSQL : 문서 : 9.2 : 토토 핫 연산자더 많은 경우 Nulls 및에 대한 정보IS 별개의.)
달러 견적은 고정 인용에만 유용하다는 점에 유의하십시오. 텍스트. 이것을 쓰려고하는 것은 매우 나쁜 생각 일 것입니다 예제 :
실행 'TBL 세트 업데이트' || quote_ident (colname) || '= $$' || NewValue || '$$ key =' || quote_literal (keyvalue);
의 내용이 끊어지기 때문에NewValue포함하여$$. 같은 반대는 어떤 것도 적용됩니다
당신이 선택할 수있는 다른 달러 인용 분리기. 안전하게
미리 알려지지 않은 견적 텍스트, 당신필수usequote_literal
, QUOTE_NULLABLE
또는QUOTE_INDEN
, 적절하게.
동적 SQL 문도 안전하게 구성 할 수 있습니다
사용 사용형식
함수 (참조PostgreSQL : 문서 : 9.2 : 스포츠 토토 결과 함수 및 연산자). 을 위한
예:
형식 실행 ( 'TBL 세트 %i = %l 여기서 key = %l', colname, newValue, keyValue);
the형식
함수 일 수 있습니다
와 함께 사용사용절 :
형식 실행 ( 'TBL 세트 업데이트 %i = $ 1 key = $ 2', colname) NewValue 사용, keyValue;
이 양식은 매개 변수이기 때문에 더 효율적입니다.NewValueandKeyValue텍스트로 변환되지 않습니다.
동적 스포츠 토토 결과의 훨씬 더 큰 예와execute예 39-8, a를 구축하고 실행합니다.생성 기능새 함수를 정의하는 스포츠 토토 결과.
명령의 효과를 결정하는 몇 가지 방법이 있습니다. 첫 번째 방법은를 사용하는 것입니다.진단양식이있는 스포츠 토토 결과 :
get [현재] 진단변수=항목[ , ... ];
이 스포츠 토토 결과은 시스템 상태 표시기를 검색 할 수 있습니다. 각항목는 핵심 단어입니다 지정된 상태에 할당 할 상태 값 식별 변수 (수신하기에 적합한 데이터 유형이어야합니다. 그것). 현재 사용 가능한 상태 항목은row_count, 마지막SQL스포츠 토토 결과으로 전송SQL엔진 및result_oid, 삽입 된 마지막 행의 OID 가장 최근SQL스포츠 토토 결과. 참고result_oid만 유용합니다 후삽입테이블에 스포츠 토토 결과 Oids 포함.
예 :
진단 받기 integer_var = row_count;
명령의 효과를 결정하는 두 번째 방법은 다음과 같습니다. 이름이 지정된 특수 변수를 확인하려면발견, 유형의부울. 발견시작합니다 각각의 거짓pl/pgsql함수 호출. 다음 유형의 각 유형에 의해 설정됩니다. 진술 :
a선택진술 세트발견행이 할당 된 경우 True 행이 반환되지 않으면 false.
a공연성명서 세트발견그것이 생산하는 경우 (및 소실) 하나 이상의 행, 행이없는 경우 거짓 생산.
업데이트, 삽입및삭제진술 세트발견true if at 최소 한 행에 영향을 받고 행이 영향을받지 않으면 거짓입니다.
afetch스포츠 토토 결과문 세트발견행을 반환하는 경우 True 행이 반환되지 않으면 false.
a움직임성명서 세트발견성공적이면 참 커서를 재배치하고, 그렇지 않으면 거짓.
afor또는foreach진술 세트발견한 번 이상 반복하면 참이되면, else false.발견이 방법으로 설정됩니다 루프가 종료 될 때; 루프 실행 내부에서발견루프에 의해 수정되지 않았습니다 진술, 실행에 의해 변경 될 수 있지만 루프 바디 내의 다른 진술.
return queryandreturn query execute진술 세트발견쿼리가 반환되는 경우 최소 1 행, 행이 반환되지 않으면 거짓.
기타PL/PGSQL진술 상태를 바꾸지 마십시오발견. 메모 특히execute변경 출력진단 받기변경되지 않음발견.
발견는 로컬 변수입니다 각PL/PGSQL함수; 어느 그것에 대한 변경은 현재 함수에만 영향을 미칩니다.
때로는 아무것도하지 않는 자리 표시 자 성명서 유용한. 예를 들어, 하나의 팔이 /then/else 체인이 의도적으로 비어 있습니다. 이를 위해 사용하십시오 그만큼NULL진술 :
null;
예를 들어, 다음 두 조각의 코드 조각입니다 동등한:
시작 Y : = x / 0; 예외 Division_by_zero가있을 때 널; - 오류를 무시하십시오 끝;
시작 Y : = x / 0; 예외 Division_By_Zero 일 때 - 오류를 무시하십시오 끝;
바람직한 맛의 문제입니다.
참고 :Oracle의 PL/SQL에서 빈 명령문 목록 허용되지 않습니다.NULL진술은필수그러한 상황 이로.pl/pgsql허용 당신은 그냥 아무것도 쓰지 않고 대신.