| Postgre토토 베이 9.0.23 문서 | ||||
|---|---|---|---|---|
| 이전 | 위로 | 39장.PL/pg토토 베이 - 토토 베이절차적 언어 | 다음 | |
이 섹션에서는 다음과 같은 구현 세부 사항에 대해 설명합니다. 자주 중요한PL/pg토토 베이사용자가 알아야 할 내용입니다.
a 내의 토토 베이 문 및 표현식PL/pg토토 베이함수는 변수를 참조할 수 있습니다. 그리고 함수의 매개변수. 비하인드 스토리,PL/pg토토 베이다음의 쿼리 매개변수를 대체합니다. 그런 참고자료. 매개변수는 장소에서만 대체됩니다. 여기서 매개변수 또는 열 참조는 구문상 허용됩니다. 극단적인 경우로, 잘못된 프로그래밍의 예를 생각해 보십시오. 스타일:
foo(foo) 값(foo)에 삽입;
다음의 첫 번째 발생foo반드시 구문상 테이블 이름이므로 대체되지 않습니다. 함수에 이름이 지정된 변수가 있더라도foo. 두 번째 항목의 이름은 다음과 같아야 합니다. 테이블의 열이므로 대체되지 않습니다. 만 세 번째 발생은 다음에 대한 참조가 될 후보입니다. 함수의 변수입니다.
참고: 포스트그레토토 베이9.0 이전 버전에서는 다음의 변수를 대체하려고 시도합니다. 세 가지 경우 모두 구문 오류가 발생합니다.
변수 이름은 구문상 다르지 않기 때문에 테이블 열 이름에서 모호함이 있을 수 있습니다. 테이블도 참조하는 명령문: 다음을 의미하는 주어진 이름입니다. 테이블 열을 참조합니까, 아니면 변수를 참조합니까? 다음을 바꾸자 이전 예
INSERT INTO dest (col) SELECT foo + bar FROM src;
여기,대상그리고src테이블 이름이어야 하며,col다음 열이어야 합니다.대상하지만foo그리고바합리적으로 둘 중 하나일 수 있습니다. 함수의 변수 또는의 열src.
기본적으로,PL/pg토토 베이할 것이다 토토 베이 문의 이름이 다음을 참조할 수 있으면 오류를 보고합니다. 변수 또는 테이블 열입니다. 그런 문제를 해결할 수 있어요 변수나 열의 이름을 바꾸거나 모호한 참조 또는 말함으로써PL/pg토토 베이어떤 해석을 선호합니다.
가장 간단한 해결책은 변수나 열의 이름을 바꾸는 것입니다. 에이 일반적인 코딩 규칙은 다른 명명 규칙을 사용하는 것입니다.PL/pg토토 베이변수가 당신보다 열 이름에 사용합니다. 예를 들어, 지속적으로 이름을 지정하는 경우 함수 변수v_뭔가당신의 열에는 아무것도 없습니다 이름은 다음으로 시작합니다.v_, 충돌이 발생하지 않습니다. 발생합니다.
또는 모호한 참조를 한정하여 만들 수 있습니다. 분명해요. 위의 예에서,src.foo에 대한 명확한 참조가 될 것입니다. 테이블 열. 변수에 대한 명확한 참조를 생성하려면, 라벨이 붙은 블록에서 선언하고 블록의 라벨을 사용합니다(참조섹션 39.2). 에 대한 예
<<블록
선언
foo int;
시작
foo := ...;
INSERT INTO dest (col) SELECT block.foo + bar FROM src;
여기block.foo변수를 의미합니다. 열이 있더라도foo에src. 함수 매개변수뿐만 아니라 다음과 같은 특수 변수발견, 할 수 있어요 함수 이름으로 한정되어야 합니다. 라벨이 붙은 외부 블록에서 암시적으로 선언되었습니다. 함수 이름입니다.
때로는 모든 모호한 문제를 해결하는 것이 비실용적입니다. 큰 본문의 참조PL/pg토토 베이코드. 그러한 경우에는 다음을 수행할 수 있습니다. 그것을 지정하십시오PL/pg토토 베이해야 한다 모호한 참조를 변수로 해결합니다(이는 호환 가능PL/pg토토 베이의 이전의 행동Postgre토토 베이9.0) 또는 테이블 열(일부 호환 가능) 다음과 같은 다른 시스템오라클).
시스템 전반에 걸쳐 이 동작을 변경하려면 구성 매개변수plpg토토 베이.variable_contribute다음 중 하나에게오류, use_variable또는use_column(어디에서오류공장 기본값임). 이 매개변수 이후의 명령문 컴파일에 영향을 줍니다.PL/pg토토 베이함수, 그러나 명령문은 아님 현재 세션에서 이미 컴파일되었습니다. 매개변수를 설정하려면 전에PL/pg토토 베이이 되었습니다 로드되었으므로 추가해야 합니다."plpg토토 베이"에custom_variable_classes목록 입력postgre토토 베이.conf. 왜냐하면 이 설정을 변경하면 의 행동PL/pg토토 베이기능, 슈퍼유저만 변경할 수 있습니다.
함수별로 동작을 설정할 수도 있습니다 기본적으로 시작 시 이러한 특수 명령 중 하나를 삽입하여 기능 텍스트 중:
#변수_충돌 오류 #변수_충돌 사용_변수 #변수_충돌 사용_열
이 명령은 작성된 기능에만 영향을 미칩니다. 그리고 설정을 재정의합니다.plpg토토 베이.variable_conflect. 예는 다음과 같습니다.
CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
#변수_충돌 사용_변수
선언
curtime 타임스탬프 := now();
시작
UPDATE 사용자 SET last_modified = curtime, 댓글 = 댓글
여기서 users.id = id;
끝;
$$ 언어 plpg토토 베이;
에서업데이트명령,커타임, 댓글및id함수를 참조합니다. 변수 및 매개변수 여부사용자에 해당 이름의 열이 있습니다. 우리는 참조를 한정해야 했습니다.users.id에서어디절을 사용하여 테이블 열을 참조하도록 합니다. 하지만 우리는 그렇지 않았습니다 참조를 한정해야 합니다.댓글대상으로업데이트목록, 왜냐하면 구문론적으로는 다음과 같아야 하기 때문입니다. 의 열사용자. 우리는 에 의존하지 않고 동일한 기능변수_충돌이런 식으로 설정:
CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
<<fn
선언
curtime 타임스탬프 := now();
시작
UPDATE 사용자 SET last_modified = fn.curtime, 댓글 = stamp_user.comment
여기서 users.id = stamp_user.id;
끝;
$$ 언어 plpg토토 베이;
명령 문자열에서 변수 대체가 발생하지 않습니다. 에게 주어졌다실행또는 그 중 하나 변형. 이러한 변수에 다양한 값을 삽입해야 하는 경우 명령을 사용하여 문자열 값 구성의 일부로 수행하거나사용 중, 그림 참조섹션 39.5.4.
변수 대체는 현재 다음에서만 작동합니다.선택, 삽입, 업데이트및삭제명령. 왜냐하면 기본 토토 베이 엔진이 이러한 명령에서만 쿼리 매개변수를 허용합니다. 사용하려면 다른 문 유형의 상수가 아닌 이름이나 값 (일반적으로 유틸리티 명령문이라고 함) 다음을 구성해야 합니다. 문자열로 된 유틸리티 설명 및실행그것.
그PL/pg토토 베이통역사 함수의 소스 텍스트를 구문 분석하고 내부 텍스트를 생성합니다. 함수가 처음 호출될 때 이진 명령 트리 (각 세션 내에서). 명령어 트리는 완전히 번역됩니다.PL/pg토토 베이성명 구조이지만 개별적임토토 베이표현 및토토 베이함수에 사용된 명령은 다음과 같습니다. 즉시 번역되었습니다.
각 표현과토토 베이명령은 다음에서 처음 실행됩니다.
함수,PL/pg토토 베이통역사는 준비된 실행 계획을 생성합니다(다음을 사용하여SPI관리자SPI_prepare및SPI_saveplan함수). 이후 방문
해당 표현식이나 명령은 준비된 계획을 재사용합니다. 따라서,
많은 문을 포함하는 조건부 코드가 있는 함수
실행 계획이 필요할 수 있는 경우에만 준비합니다.
평생 동안 실제로 사용되는 계획을 저장하십시오.
데이터베이스 연결의. 이렇게 하면 비용을 크게 줄일 수 있습니다.
실행을 구문 분석하고 생성하는 데 필요한 총 시간
a의 진술에 대한 계획PL/pg토토 베이함수. 단점은
특정 표현식이나 명령의 오류를 감지할 수 없습니다.
함수의 해당 부분이 실행될 때까지.
(사소한 구문 오류는 초기 단계에서 감지됩니다.
구문 분석 패스를 수행하지만 더 깊은 것은 감지될 때까지 감지되지 않습니다.
실행.)
저장된 계획은 다음과 같은 경우 자동으로 다시 계획됩니다. 쿼리에 사용된 테이블에 대한 스키마 변경 사항이 있는 경우 쿼리에 사용된 사용자 정의 함수가 재정의되었습니다. 이 대부분의 경우 준비된 계획을 투명하게 재사용합니다. 하지만 오래된 계획을 재사용할 수 있는 특수한 경우가 있습니다. 예를 들어 사용자 정의 항목을 삭제하고 다시 만드는 경우가 있습니다. 연산자는 이미 캐시된 계획에 영향을 주지 않습니다. 그들은 계속해서 원래 연산자의 기본 함수를 호출합니다(있는 경우). 변경되지 않았습니다. 필요한 경우 캐시를 플러시할 수 있습니다. 새로운 데이터베이스 세션을 시작합니다.
왜냐하면PL/pg토토 베이저장 이런 식으로 실행 계획을 세우면 토토 베이 명령어가 직접적으로 나타나 에서PL/pg토토 베이함수는 반드시 모든 실행에서 동일한 테이블과 열을 참조하십시오. 그 즉, 매개변수를 테이블이나 열의 이름으로 사용할 수 없습니다. 토토 베이 명령에서. 이 제한 사항을 해결하려면 다음을 수행하십시오. 를 사용하여 동적 명령을 구성합니다.PL/pg토토 베이 실행성명 — 새로운 실행 계획을 세우는 대가로 실행될 때마다.
또 다른 중요한 점은 준비된 계획이 값을 허용하도록 매개변수화됨PL/pg토토 베이한 번 사용으로 변경되는 변수 위에서 자세히 설명한 대로 다음으로 넘어갑니다. 때로는 이것이 의미하는 바 계획이 생성된 경우보다 효율성이 떨어집니다. 특정 변수 값. 예를 들어 다음을 고려하세요.
SELECT * INTO myrec FROM Dictionary WHERE word LIKE search_term;
어디에서search_term은PL/pg토토 베이변수. 캐시된 계획 이 쿼리는 인덱스를 절대 사용하지 않습니다.단어, 플래너는 다음을 가정할 수 없으므로좋아요패턴이 왼쪽 고정됩니다 런타임에. 인덱스를 사용하려면 쿼리를 다음과 같이 계획해야 합니다. 특정 상수좋아요패턴 제공됩니다. 이것은 또 다른 상황입니다.실행새로운 계획을 강제로 실행하는 데 사용될 수 있습니다. 각 실행마다 생성됩니다.
레코드 변수의 변경 가능 특성은 또 다른 특징을 제시합니다. 이와 관련하여 문제가 있습니다. 레코드 변수의 필드가 있는 경우 표현식이나 명령문에 사용되는 데이터 유형 필드는 한 번의 함수 호출에서 다음으로 변경되어서는 안 됩니다. 다음으로, 각 표현식은 데이터 유형을 사용하여 계획되므로 표현식에 처음 도달할 때 존재합니다.실행이 문제를 해결하는 데 사용할 수 있습니다 필요할 때 문제가 발생합니다.
동일한 함수가 둘 이상의 트리거로 사용되는 경우 테이블,PL/pg토토 베이준비하고 각 테이블에 대해 독립적으로 계획을 캐시합니다. 각 트리거 기능과 테이블 조합에 대한 캐시입니다. 각 기능마다. 이를 통해 일부 문제가 완화됩니다. 다양한 데이터 유형으로; 예를 들어 트리거 기능은 이름이 지정된 열을 사용하여 성공적으로 작업할 수 있습니다.키우연히 다른 유형이 있더라도 다른 테이블에 있습니다.
마찬가지로, 다형성 인수 유형을 갖는 함수는 실제 인수의 각 조합에 대해 별도의 계획 캐시 호출된 유형이므로 데이터 유형이 다릅니다. 예상치 못한 오류가 발생하지 않도록 하세요.
계획 캐싱은 때때로 계획에 놀라운 영향을 미칠 수 있습니다. 시간에 민감한 값의 해석. 예를 들어 이 두 함수가 수행하는 작업의 차이점은 다음과 같습니다.
함수 생성 logfunc1(logtxt text) $$로 무효 반환
시작
INSERT INTO 로그 테이블 VALUES(logtxt, 'now');
끝;
$$ 언어 plpg토토 베이;
그리고:
CREATE FUNCTION logfunc2(logtxt text) 반환 $$로 무효
선언
curtime 타임스탬프;
시작
curtime := '지금';
INSERT INTO 로그 테이블 VALUES(logtxt, curtime);
끝;
$$ 언어 plpg토토 베이;
다음의 경우logfunc1, 그Postgre토토 베이메인 파서는 알고 있습니다
계획을 준비할 때삽입그 문자열'지금'해야 합니다
다음과 같이 해석됨타임스탬프, 왜냐하면
대상 열로그테이블다음 중
그 유형. 따라서,'지금'될 것이다
다음과 같은 경우 상수로 변환됩니다.삽입계획되어 있으며 모든 용도로 사용됩니다.
호출logfunc1중
세션의 수명. 말할 필요도 없이 이건 아니다.
프로그래머가 원했어요.
다음의 경우logfunc2, 그Postgre토토 베이주 파서가 수행하는 작업
어떤 유형인지 모르겠습니다'지금'다음과 같아야 합니다
따라서 유형의 데이터 값을 반환합니다.텍스트문자열 포함지금. 이후 현지 임무를 수행하는 동안
변수커타임, 그PL/pg토토 베이인터프리터는 이 문자열을 다음으로 변환합니다.타임스탬프다음을 호출하여 입력text_out그리고timestamp_in변환을 위한 함수.
따라서 계산된 타임스탬프는 실행될 때마다 업데이트됩니다.
프로그래머는 기대합니다.