Postgresql 9.0.23 문서화 | ||||
---|---|---|---|---|
PostgreSQL : 문서 : 9.0 : 젠 토토 프로 시저 | up | 39 장.pl/pg토토 베이 - 토토 베이절차 언어 | 다음 |
이 섹션에서는 일부 구현 세부 정보에 대해 설명합니다 자주pl/pg토토 베이사용자가 알고 있습니다.
a 내 토토 베이 문 및 표현식pl/pg토토 베이함수는 변수를 참조 할 수 있습니다 및 함수의 매개 변수. 무대 뒤에서pl/pg토토 베이쿼리 매개 변수를 대체합니다 그러한 참조. 매개 변수는 장소에서만 대체됩니다 파라미터 또는 열 참조가 구문 적으로 허용되는 경우. 극단적 인 경우, 열악한 프로그래밍의 예를 고려하십시오. 스타일:
foo (foo) 값 (foo)에 삽입;
첫 번째 발생foo필수 구문 적으로 테이블 이름이므로 대체되지 않습니다. 함수의 변수가가 있더라도foo. 두 번째 발생은 a의 이름이어야합니다 테이블의 열이므로 대체되지 않습니다. 오직 세 번째 사건은 후보입니다. 함수 변수.
참고 : Postgre토토 베이9.0 이전 버전은 변수를 대체하려고합니다. 세 가지 경우 모두 구문 오류로 이어집니다.
변수의 이름은 구문 적으로 다르지 않기 때문입니다 테이블 열의 이름에서 표를 참조하는 진술 : 주어진 이름은 테이블 열 또는 변수를 참조하십시오. 바꾸자 이전의 예
dest에 삽입 (col) src에서 foo + bar를 선택하십시오.
여기,destandSRC테이블 이름이어야합니다.coldest그러나fooandbar합리적으로있을 수 있습니다 함수의 변수 또는SRC.
기본적으로pl/pg토토 베이의지 토토 베이 문의 이름이 변수 또는 테이블 열. 그러한 문제를 해결할 수 있습니다 변수 또는 열을 바꾸거나 모호한 참조 또는 말하기pl/pg토토 베이어떤 해석 선호하다.
가장 간단한 솔루션은 변수 또는 열의 이름을 바꾸는 것입니다. 에이 일반적인 코딩 규칙은에 대해 다른 명명 규칙을 사용하는 것입니다.pl/pg토토 베이당신보다 변수 열 이름에 사용됩니다. 예를 들어, 지속적으로 이름을 지정하는 경우 함수 변수V_뭔가열 중 어느 것도 없습니다 이름으로 시작V_, 충돌은 없습니다 발생하다.
또는 대안 적으로 모호한 참조를 할 수 있습니다 분명합니다. 위의 예에서src.foo표 열. 변수에 대한 명백한 참조를 만들려면 라벨이 붙은 블록에 선언하고 블록의 레이블을 사용하십시오 (참조Postgre토토 핫 : 문서 : 9.0 : PL/PG토토 핫의 구조). 을 위한 예,
<< 블록 선언하다 foo int; 시작하다 foo : = ...; SRC에서 DEST (COL)에 삽입 (COL) SELECT BLOCK.FOO + BAR;
여기block.foo변수를 의미합니다 열이 있더라도fooinSRC. 기능 매개 변수뿐만 아니라 와 같은 특수 변수발견, can 함수 이름에 따라 자격을 갖추십시오 암시 적으로 라벨이 붙은 외부 블록에서 암시 적으로 선언되었습니다 기능의 이름.
때로는 모호한 것을 모두 고치는 것이 비현실적입니다 큰 몸에서의 참조pl/pg토토 베이코드. 그러한 경우에 당신은 할 수 있습니다 이를 지정pl/pg토토 베이변수로 모호한 참조를 해결하십시오 (즉 호환pl/pg토토 베이's 이전의 행동Postgre토토 베이9.0) 또는 테이블 열 (일부와 호환됩니다. 와 같은 기타 시스템Oracle).
시스템 전체에 따라이 동작을 변경하려면 구성 매개 변수plpg토토 베이.variable_conflict오류, use_variable또는use_column(where오류공장 기본값입니다). 이 매개 변수 의 후속 문자에 영향을 미칩니다pl/pg토토 베이기능이지만 진술은 아닙니다 현재 세션에서 이미 컴파일되었습니다. 매개 변수를 설정합니다 전에pl/pg토토 베이로드, 추가해야합니다"PLPG토토 베이"to thecustom_variable_classesList inpostgre토토 베이.conf. 왜냐하면 이 설정을 변경하면 예상치 못한 변경이 발생할 수 있습니다 행동pl/pg토토 베이함수, 슈퍼업자에 의해서만 변경 될 수 있습니다.
당신은 또한 기능별로 동작을 설정할 수도 있습니다 기본, 처음에 이러한 특별 명령 중 하나를 삽입하여 함수 텍스트의 :
#Variable_Conflict 오류 #variable_conflict use_variable #variable_conflict use_column
이 명령은 작성된 함수에만 영향을 미칩니다. 의 설정을 무시합니다plpg토토 베이.variable_conflict. 예는입니다.
함수 만들기 stamp_user (id int, 댓글 텍스트)는 void를 $$로 반환합니다. #variable_conflict use_variable 선언하다 Curtime timestamp : = now (); 시작하다 업데이트 사용자가 set last_modified = curtime, comment = comment 여기서 users.id = id; 끝; $$ 언어 plpgsql;
in업데이트명령,CURTIME, 댓글및id함수를 참조합니다 변수 및 매개 변수 여부사용자그 이름의 열이 있습니다. 우리가 주목하십시오 에 대한 참조 자격을 갖추어야했습니다users.idin여기서테이블 열을 참조하는 조항. 그러나 우리는하지 않았다 에 대한 참조 자격을 갖추어야합니다.댓글의 대상으로업데이트구문 적 으로야하기 때문에 열사용자. 우리는 쓸 수 있습니다 에 따라 동일한 기능variable_conflict이런 식으로 설정 :
함수 만들기 stamp_user (id int, 댓글 텍스트)는 void를 $$로 반환합니다. << fn 선언하다 Curtime timestamp : = now (); 시작하다 업데이트 사용자가 set last_modified = fn.curtime, comment = stamp_user.comment입니다 여기서 users.id = stamp_user.id; 끝; $$ 언어 plpgsql;
명령 문자열에서 변수 대체가 발생하지 않습니다 주어진execute또는 그 중 하나 변형. 그러한 값에 다양한 값을 삽입 해야하는 경우 명령, 문자열 값 구성의 일부로 그렇게하거나 사용사용,섹션 39.5.4.
가변 대체는 현재에서만 작동합니다select, 삽입, 업데이트및삭제기본 토토 베이 엔진이기 때문에 명령 이 명령에서만 쿼리 매개 변수를 허용합니다. 사용하려면 다른 명령문 유형의 비정상적인 이름 또는 값 (일반적으로 유틸리티 명세서라고 불림)를 구성해야합니다 문자열로서의 유틸리티 진술 및executeit.
thepl/pg토토 베이통역사 함수의 소스 텍스트를 구문 분석하고 내부를 생성합니다 이진 명령 트리 기능이 처음으로 호출되는 경우 (각 세션 내에서). 지침 트리는 완전히 번역됩니다 그만큼pl/pg토토 베이진술 구조이지만 개인토토 베이표현 및토토 베이함수에 사용 된 명령은 그렇지 않습니다 즉시 번역.
각 표현 및토토 베이명령에서 처음 실행됩니다
기능,pl/pg토토 베이통역사는 준비된 실행 계획을 만듭니다 (사용SPI관리자SPI_PREPARE
andSPI_SAVEPLAN
기능). 후속 방문
그 표현 또는 명령은 준비된 계획을 재사용합니다. 따라서, a
많은 진술이 포함 된 조건부 코드로 기능합니다
실행 계획이 필요한 경우 만
일생 동안 실제로 사용되는 계획을 저장하십시오.
데이터베이스 연결의. 이것은 실질적으로 감소 할 수 있습니다
구문 분석 및 실행을 생성하는 데 필요한 총 시간
A의 진술 계획PL/PG토토 베이함수. 단점은 그게됩니다
특정 표현식 또는 명령의 오류를 감지 할 수 없습니다.
함수의 해당 부분이 실행 중에 도달 할 때까지.
(초기에 Trivial Syntax 오류가 감지됩니다
구문 분석 패스이지만 더 깊은 것은
실행.)
저장된 계획이있는 경우 자동으로 다시 계획됩니다. 모든 스키마가 쿼리에 사용 된 모든 테이블로 변경되거나 쿼리에 사용 된 사용자 정의 함수는 재정의되었습니다. 이것 대부분의 경우 준비된 계획의 재사용을 투명하게합니다. 그러나 오래된 계획이 재사용 될 수있는 코너 사례가 있습니다. 예를 들어, 사용자 정의를 삭제하고 재창조하는 것입니다 운영자는 이미 성장한 계획에 영향을 미치지 않습니다. 그들은 계속할 것입니다 원래 운영자의 기본 기능을 호출하십시오 변경되지 않았습니다. 필요한 경우 캐시를 플러시 할 수 있습니다 새로운 데이터베이스 세션 시작.
때문에pl/pg토토 베이저장 이러한 방식으로 실행 계획, 직접 나타나는 토토 베이 명령 에서pl/pg토토 베이함수가 있어야합니다 모든 실행에서 동일한 테이블과 열을 참조하십시오. 저것 매개 변수를 테이블 또는 열의 이름으로 사용할 수 없습니다. 토토 베이 명령에서. 이 제한을 해결하려면 가능합니다 를 사용하여 동적 명령 구성pl/pg토토 베이 execute성명서 - 새로운 실행 계획을 세우는 대가로 모든 실행에.
또 다른 중요한 요점은 준비된 계획이라는 것입니다 값을 허용하도록 매개 변수화PL/PG토토 베이한 번의 사용에서 변경되는 변수 다음에, 위에서 자세히 설명한 바와 같이. 때때로 이것은 의미합니다 계획이 생성되는 경우보다 덜 효율적이라는 특정 변수 값. 예를 들어, 고려
선택 * 사전에서 Myrec에 * search_term;
여기서search_termispl/pg토토 베이변수. 캐시 된 계획 이 쿼리는 in index를 사용하지 않습니다Word, 플래너는 그것을 가정 할 수 없기 때문에 그만큼좋아요패턴은 좌회전됩니다 런타임에. 색인을 사용하려면 쿼리를 특정 상수좋아요패턴 제공. 이것은 또 다른 상황입니다execute새로운 계획을 강요하는 데 사용될 수 있습니다. 각 실행에 대해 생성됩니다.
레코드 변수의 변이 성 특성은 다른 것을 제시합니다 이와 관련하여 문제. 레코드 변수의 필드 표현 또는 명세서, 데이터 유형에 사용됩니다. 필드는 함수의 한 호출에서 다음으로, 각 표현식은 데이터 유형을 사용하여 계획되므로 그것은 표현이 처음 도달 할 때 존재합니다.execute이 주위를 돌리는 데 사용될 수 있습니다 필요한 경우 문제.
동일한 함수가 둘 이상의 트리거로 사용되는 경우 테이블,pl/pg토토 베이준비 및 캐시는 그러한 각 테이블에 대해 독립적으로 계획, 즉 거기에 있습니다. 각 트리거 기능 및 테이블 조합에 대한 캐시입니다. 각 함수에 대해. 이것은 일부 문제를 완화시킵니다 다양한 데이터 유형으로; 예를 들어 트리거 함수가됩니다 라는 열로 성공적으로 작업 할 수 있어야합니다.키다른 유형이 다른 경우에도 다른 테이블에서.
마찬가지로 다형성 인수 유형을 갖는 기능에는 a가 있습니다 실제 인수의 각 조합에 대해 별도의 계획 캐시 데이터 유형 차이가 있도록 촉진 된 유형 예상치 못한 실패를 일으키지 마십시오.
계획 캐싱은 때때로 놀라운 영향을 미칠 수 있습니다 시간에 민감한 값의 해석. 예를 들어 a가 있습니다 이 두 기능의 차이점 :
함수 생성 logfunc1 (logtxt 텍스트)은 $$로 void를 반환합니다 시작하다 Logtable 값 (logtxt, 'now')에 삽입; 끝; $$ 언어 plpgsql;
및 :
함수 생성 logfunc2 (logtxt 텍스트)는 void를 $$로 반환합니다 선언하다 곡선 타임 스탬프; 시작하다 큐 타임 : = '지금'; Logtable 값 (logtxt, curtime)에 삽입; 끝; $$ 언어 plpgsql;
의 경우logfunc1
, ThePostgre토토 베이Main Parser는 알고 있습니다
계획을 준비 할 때삽입그 문자열'now'로 해석타임 스탬프의 대상 열logtable
그 유형. 따라서,'now'일시 상수로 변환삽입가 계획된 다음 모든 것에 사용됩니다
의 호출logfunc1
세션의 수명. 말할 것도없이, 이것은 무엇이 아닙니다
프로그래머가 원했습니다.
의 경우logfunc2
, ThePostgre토토 베이메인 파서입니다
어떤 유형을 모른다'now'따라서 유형의 데이터 값을 반환합니다텍스트문자열 포함now. 다음으로 현지인에게 임무를 수행하는 동안
변하기 쉬운CURTIME,pl/pg토토 베이인터프리터는이 문자열을 캐스트합니다
그만큼타임 스탬프전화하여 타이핑text_out
andTimestamp_in
변환 기능.
따라서 계산 된 타임 스탬프는 각 실행에 따라
프로그래머가 기대합니다.