이 섹션은 자주 중요한 구현 세부 사항에 대해 설명합니다.윈 토토/pgsql사용자가 알고 있습니다.
a 내 SQL 문 및 표현식윈 토토/pgsql함수는 함수의 변수와 매개 변수를 참조 할 수 있습니다. 무대 뒤에서윈 토토/pgsql그러한 참조의 쿼리 매개 변수를 대체합니다. 쿼리 매개 변수는 구문 적으로 허용되는 장소에서만 대체됩니다. 극단적 인 경우, 열악한 프로그래밍 스타일 의이 예를 고려하십시오.
foo (foo) 값 (foo (foo))에 삽입;
첫 번째 발생foo
구문 적으로 테이블 이름이어야하므로 함수의 변수가있는 경우에도 대체되지 않아야합니다.foo
. 두 번째 발생은 해당 테이블의 열의 이름이어야하므로 대체되지 않습니다. 마찬가지로 세 번째 발생은 함수 이름이어야하므로 대체되지 않습니다. 마지막 사건만이의 변수에 대한 언급의 후보입니다.윈 토토/pgsql기능.
이를 이해하는 또 다른 방법은 변수 대체가 데이터 값을 SQL 명령에만 삽입 할 수 있다는 것입니다. 명령에 의해 참조되는 데이터베이스 개체를 동적으로 변경할 수 없습니다. (그렇게하려면에 설명 된대로 명령 문자열을 동적으로 구축해야합니다.섹션 43.5.4.)
변수 이름은 표 열의 이름과 구문 적으로 다르지 않기 때문에 표를 참조하는 명령문에는 모호성이있을 수 있습니다. 주어진 이름은 테이블 열을 참조 할 수 있습니까? 이전 예를 변경하자
dest에 삽입 (col) SRC에서 foo + bar를 선택하십시오.
여기,dest
andSRC
테이블 이름이어야합니다.col
이어야합니다.dest
그러나foo
및bar
| 함수의 변수 또는 열 변수 일 수 있습니다.SRC
.
기본적으로윈 토토/pgsqlSQL 문의 이름이 변수 또는 테이블 열을 참조 할 수있는 경우 오류를보고합니다. 변수 또는 열 이름을 바꾸거나 모호한 참조 자격을 갖추거나 말함으로써 그러한 문제를 해결할 수 있습니다윈 토토/pgsql선호하는 해석.
가장 간단한 솔루션은 변수 또는 열의 이름을 바꾸는 것입니다. 일반적인 코딩 규칙은에 대해 다른 명명 규칙을 사용하는 것입니다.윈 토토/pgsql열 이름에 사용하는 것보다 변수. 예를 들어, 지속적으로 함수 변수 이름을 지정하는 경우V_
열 이름 중 어느 것도 시작하는 동안뭔가
V_
, 충돌이 발생하지 않을 것입니다.
또는 대안 적으로 당신은 모호한 참조를 명확하게 할 수 있습니다. 위의 예에서src.foo
테이블 열에 대한 명백한 참조입니다. 변수에 대한 명백한 참조를 만들려면 레이블이 붙은 블록에 선언하고 블록의 레이블을 사용하십시오 (참조배트맨 토토 PostgreSQL : 문서 : 14 : 43.2. pl/pgsql의 구조). 예를 들어,
<< 블록 선언하다 foo int; 시작하다 foo : = ...; SRC에서 DEST (COL)에 삽입 (COL) SELECT BLOCK.FOO + BAR;
여기block.foo
열이 있더라도 변수를 의미foo
inSRC
. 함수 매개 변수 및와 같은 특수 변수발견
, 함수 이름으로 표시된 외부 블록에서 암시 적으로 선언되기 때문에 함수 이름에 따라 자격을 갖추 수 있습니다..
때로는 큰 본문에서 모든 모호한 참조를 고치는 것이 비현실적입니다윈 토토/pgsql코드. 그러한 경우를 지정할 수 있습니다.윈 토토/pgsql변수로 모호한 참조를 해결해야합니다 (윈 토토/pgsql의 행동 전postgresql9.0) 또는 테이블 열로 (과 같은 일부 시스템과 호환됩니다Oracle).
시스템 전체 에서이 동작을 변경하려면 구성 매개 변수를 설정하십시오.윈 토토pgsql.variable_conflict
오류
, use_variable
또는use_column
(where오류
공장 기본값입니다). 이 매개 변수는 다음의 후속 문자 편집에 영향을 미칩니다윈 토토/pgsql함수이지만 현재 세션에서 이미 수집되지 않은 진술은 없습니다. 이 설정을 변경하면의 동작에 예상치 못한 변화가 발생할 수 있기 때문입니다.윈 토토/pgsql함수, 슈퍼업자에 의해서만 변경 될 수 있습니다.
기능 텍스트의 시작 부분에서 이러한 특수 명령 중 하나를 삽입하여 기능별로 동작을 설정할 수도 있습니다.
#variable_conflict 오류 #variable_conflict use_variable #variable_conflict use_column
이 명령은 작성된 함수에만 영향을 미치고의 설정을 무시합니다.윈 토토pgsql.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.id
in여기서
테이블 열을 참조하기위한 조항. 그러나 우리는에 대한 참조 자격을 갖추지 않아도됩니다.댓글
의 대상으로업데이트
목록, 구문 적으로이어야하기 때문에사용자
. 우리는에 따라 동일한 기능을 쓸 수 있습니다.variable_conflict
이런 식으로 설정 :
함수 만들기 Stamp_user (id int, 댓글 텍스트)를 $$로 반환합니다. << fn 선언하다 Curtime timestamp : = now (); 시작하다 업데이트 사용자가 set last_modified = fn.curtime, comment = stamp_user.comment입니다 여기서 users.id = stamp_user.id; 끝; $$ 언어 plpgsql;
가변 대체는에 주어진 명령 문자열에서 발생하지 않습니다.execute
또는 그 변형 중 하나. 그러한 명령에 다양한 값을 삽입 해야하는 경우 문자열 값 구성의 일부로 그렇게하거나사용
,섹션 43.5.4.
가변 대체는 현재에서만 작동합니다select
, 삽입
, 업데이트
, 삭제
및 이들 중 하나를 포함하는 명령 (예 :설명
and테이블 작성 ... 선택
), 기본 SQL 엔진은이 명령에서만 쿼리 매개 변수를 허용하기 때문입니다. 다른 명령문 유형 (일반적으로 유틸리티 명령문이라고 함)에서 비정상적인 이름 또는 값을 사용하려면 유틸리티 문을 문자열로 구성하고execute
it.
the윈 토토/pgsql통역사는 함수의 소스 텍스트를 구문 분석하고 기능을 처음으로 호출 할 때 내부 이진 명령 트리를 생성합니다 (각 세션 내에서). 지침 트리는를 완전히 번역합니다.윈 토토/pgsql진술 구조, 그러나 개인SQL표현 및SQL함수에 사용 된 명령은 즉시 변환되지 않습니다.
각 표현 및SQL명령은 기능에서 처음 실행됩니다.윈 토토/pgsql통역사는 명령을 구문 분석하고 분석하여 준비된 진술을 작성하여SPI관리자SPI_PREPARE
함수. 그 표현에 대한 후속 방문 또는 명령은 준비된 진술을 재사용합니다. 따라서, 거의 방문하지 않는 조건부 코드 경로가있는 함수는 현재 세션 내에서 결코 실행되지 않는 명령을 분석하는 오버 헤드가 발생하지 않습니다. 단점은 특정 표현식 또는 명령의 오류가 함수의 일부에 실행 중에 도달 할 때까지 감지 할 수 없다는 것입니다. (초기 구문 분석 패스 중에는 Trivial Syntax 오류가 감지되지만 실행 될 때까지 더 깊은 것은 감지되지 않습니다.)
윈 토토/pgsql(또는 더 정확하게 SPI 관리자)는 또한 특정 준비된 진술과 관련된 실행 계획을 캐시하려고 시도 할 수 있습니다. 캐시 된 계획이 사용되지 않으면 문을 방문 할 때마다 새로운 실행 계획이 생성되고 현재 매개 변수 값 (즉,윈 토토/pgsql변수 값)를 사용하여 선택한 계획을 최적화 할 수 있습니다. 문에 매개 변수가 없거나 여러 번 실행되는 경우 SPI 관리자는 A 생성을 고려합니다.제네릭특정 매개 변수 값에 의존하지 않는 계획 및 재사용을위한 캐싱. 일반적으로 이것은 실행 계획이 값에별로 민감하지 않은 경우에만 발생합니다.윈 토토/pgsql변수에 참조. 그렇다면 매번 계획을 생성하는 것은 순 승리입니다. 보다준비준비된 진술의 행동에 대한 자세한 내용은
왜냐하면윈 토토/pgsql준비된 진술을 저장하고 때로는 이러한 방식으로 실행 계획을 저장합니다.PL/PGSQL함수는 모든 실행에서 동일한 테이블과 열을 참조해야합니다. 즉, 매개 변수를 SQL 명령의 테이블 또는 열의 이름으로 사용할 수 없습니다. 이 제한 사항을 해결하려면를 사용하여 동적 명령을 구축 할 수 있습니다.윈 토토/pgsql execute
성명서 - 새로운 구문 분석 분석을 수행하고 모든 실행에 대한 새로운 실행 계획을 세우는 대가로.
레코드 변수의 변이 가능한 특성은 이와 관련하여 또 다른 문제를 제시합니다. 레코드 변수의 필드가 표현식 또는 명령문에 사용되면 필드의 데이터 유형은 기능의 한 호출에서 다음 호출로 변경해서는 안됩니다. 각 표현식은 표현식에 도달 할 때 존재하는 데이터 유형을 사용하여 분석되므로..execute
필요할 때이 문제를 해결하는 데 사용할 수 있습니다.
동일한 함수가 둘 이상의 테이블의 트리거로 사용되는 경우윈 토토/pgsql그러한 각 테이블에 대해 독립적으로 명세서를 준비하고 캐시합니다. 즉, 각 기능뿐만 아니라 각 트리거 기능 및 테이블 조합에 대한 캐시가 있습니다. 이것은 다양한 데이터 유형의 일부 문제를 완화시킵니다. 예를 들어 트리거 함수는라는 열에서 성공적으로 작동 할 수 있습니다.키
다른 테이블에 다른 유형이있는 경우에도
마찬가지로, 다형성 인수 유형을 갖는 기능은 그들이 호출 한 실제 인수 유형의 각 조합에 대해 별도의 명령문 캐시를 가지고 있으므로 데이터 유형 차이가 예상치 못한 실패를 유발하지 않도록합니다.
Statement Caching은 때때로 시간에 민감한 값의 해석에 놀라운 영향을 미칠 수 있습니다. 예를 들어이 두 기능 사이에는 차이가 있습니다.
함수 생성 logfunc1 (logtxt 텍스트)은 $$로 void를 반환합니다 시작하다 Logtable 값 (logtxt, 'now')에 삽입; 끝; $$ 언어 plpgsql;
및 :
함수 생성 logfunc2 (logtxt 텍스트)는 void를 $$로 반환합니다 선언하다 곡선 타임 스탬프; 시작하다 큐 타임 : = '지금'; Logtable 값 (logtxt, curtime)에 삽입; 끝; $$ 언어 plpgsql;
의 경우logfunc1
, ThePostgreSQLMain Parser는 분석 시점을 알고 있습니다삽입
String'지금'
타임 스탬프
,의 대상 열이기 때문에logtable
그 유형입니다. 따라서,'now'
A로 변환됩니다타임 스탬프
삽입
분석 된 다음의 모든 호출에 사용됩니다.logfunc1
세션 수명 동안. 말할 것도없이, 이것은 프로그래머가 원했던 것이 아닙니다. 더 나은 아이디어는 사용하는 것입니다.now ()
또는current_timestamp
기능.
의 경우logfunc2
, ThepostgresqlMain Parser는 어떤 유형을 모릅니다'now'
따라서 유형의 데이터 값을 반환해야합니다.텍스트
문자열 포함now
. 이어지는 지역 변수에 대한 할당 중CURTIME
, The윈 토토/pgsql통역사는이 문자열을에 캐스팅합니다.타임 스탬프
전화하여 타이핑텍스트 아웃
및Timestamp_in
변환 기능. 따라서 컴퓨팅 타임 스탬프는 프로그래머가 예상하는대로 각 실행에 대해 업데이트됩니다. 이것은 예상대로 작동하지만 크게 효율적이지 않으므로 사용하십시오.now ()
함수는 여전히 더 나은 아이디어가 될 것입니다.
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면