이 섹션에서는 일부 구현 세부 정보에 대해 설명합니다 자주토토 사이트/pgsql사용자가 알고 있습니다.
언제토토 사이트/pgsql준비 a 실행을위한 SQL 명령문 또는 표현, 모든토토 사이트/pgsql가변 이름이 나타납니다 명령문 또는 표현식은 매개 변수 기호로 대체됩니다.$n. 그런 다음 변수의 현재 값이 값으로 제공됩니다. 문 또는 표현식이있을 때마다 매개 변수의 경우 실행. 예를 들어, 함수를 고려
함수 생성 logfunc (logtxt 텍스트)는 void를 $$로 반환합니다 선언하다 Curtime timestamp : = now (); 시작하다 Logtable 값 (logtxt, curtime)에 삽입; 끝; $$ 언어 토토 사이트pgsql;
the삽입성명서 효과적으로로 처리됩니다.
준비station_name(텍스트, 타임 스탬프) AS 로그 테이블 값 ($ 1, $ 2)에 삽입;
|execute의 현재 실제 값과 함께 두 변수. (참고 : 여기서 우리는 주요 SQL에 대해 말하고 있습니다 엔진와이즈 토토 : 문서 : 8.3 : execute명령, 아님토토 사이트/pgsql'sexecute.)
대체 메커니즘은 알려진 것과 일치하는 모든 토큰을 대체합니다 변수 이름.이것은 다양한 트랩을 포즈합니다 조심성 없는. 예를 들어 변수 이름을 사용하는 것은 나쁜 생각입니다. 그것은 당신이 필요로하는 모든 테이블 또는 열 이름과 동일합니다. 기능 내에서 쿼리를 참조하십시오 생각은 테이블 또는 열 이름이 여전히 교체됩니다. 에서 위의 예,logtable열 이름이 있습니다logtxtandlogtime삽입as
logtable (logtxt, logtime) 값 (logtxt, curtime)에 삽입;
이것은 기본 SQL 파서에게 공급됩니다.
logtable에 삽입 ($ 1, logtime) 값 ($ 1, $ 2);
다음과 같은 구문 오류가 발생합니다.
오류 : "$ 1"또는 근처의 구문 오류 1 행 : Logtable ($ 1, logtime) 값에 삽입 ($ 1, $ 2) ^ 쿼리 : logtable ($ 1, logtime) 값 ($ 1, $ 2)에 삽입 컨텍스트 : 토토 사이트/pgsql 함수의 SQL 문 "logfunc2"근처 5
이 예제는 진단하기 쉽습니다. 명백한 구문 오류. 많은 경우가 있습니다 대체는 구문 적으로 허용됩니다 증상은 기능의 잘못된 행동 일 수 있습니다. 어떤 경우에는 사용자입니다 다음과 같이 썼습니다 :
선언 val 텍스트; search_key 정수; 시작하다 ... key = search_key loop ... 인 테이블에서 val의 val의 경우
그리고 왜 그의 모든 테이블 항목이 무효 인 것처럼 보이는지 궁금했습니다. 의 여기서 일어난 일은 쿼리가되었다는 것이 었습니다.
key = $ 2 테이블에서 $ 1을 선택하십시오.
따라서 그것은 단지 비싼 할당 방법이었습니다val의 현재 값은 그 자체로 돌아 왔습니다 각 행.
그러한 함정을 피하기위한 일반적으로 사용되는 코딩 규칙은 다음과 같습니다. 다른 이름 지정 규칙을 사용하여토토 사이트/pgsql테이블에 사용하는 것보다 변수 및 열 이름. 예를 들어, 모든 변수가 이름이 지정된 경우V_뭔가당신의 테이블은 없지만 또는 열 이름으로 시작V_, 당신은입니다 꽤 안전합니다.
또 다른 해결 방법은 자격을 갖춘 (점선) 이름을 사용하는 것입니다 SQL 엔티티. 예를 들어 우리는 안전하게 쓸 수있었습니다 위의 예제 as
select table의 val의 경우 key = search_key loop ... 테이블에서 val.
왜냐하면토토 사이트/pgsql그렇지 않습니다 자격을 갖춘 후행 구성 요소로 변수를 대체 이름. 그러나이 솔루션은 모든 경우에 작동하지는 않습니다. 에서 이름을받을 수 없습니다.삽입's 예를 들어 열 이름 목록입니다. 또 다른 요점은 그 기록입니다 행 변수 이름은 첫 번째 구성 요소와 일치합니다. 자격을 갖춘 이름으로 자격을 갖춘 SQL 이름은 여전히 취약합니다. 어떤 경우에는. 그러한 경우 비 분쇄를 선택하는 경우 변수 이름은 유일한 방법입니다.
당신이 사용할 수있는 또 다른 기술은 라벨을 변수가 선언 된 다음 자격을 갖춘 블록 SQL 명령의 변수 이름 (참조섹션 38.2). 예를 들어,
<< pl 선언하다 val 텍스트; 시작하다 ... 업데이트 테이블 세트 col = pl.val where ...
이것은 그 자체로 문제에 대한 해결책이 아닙니다. 충돌, SQL 명령의 자격이없는 이름은 여전히 해석 될 위험에 처해"잘못된"웨이. 그러나 명확히하는 데 유용합니다 잠재적으로 모호한 코드의 의도.
명령 문자열에서 변수 대체가 발생하지 않습니다 주어진execute또는 그 중 하나 변형. 그러한 값에 다양한 값을 삽입 해야하는 경우 명령, 문자열 값 구성의 일부로 그렇게하십시오. 에 묘사섹션 38.5.4.
가변 대체는 현재에서만 작동합니다select, 삽입, 업데이트및삭제기본 SQL 엔진이기 때문에 명령 이 명령에서만 매개 변수 기호를 허용합니다. 사용하려면 다른 명령문 유형의 비정상적인 이름 또는 값 (일반적으로 유틸리티 명세서라고 불림)를 구성해야합니다 문자열로서의 유틸리티 진술 및executeit.
the토토 사이트/pgsql통역사 함수의 소스 텍스트를 구문 분석하고 내부를 생성합니다 이진 명령 트리 기능이 처음으로 호출되는 경우 (각 세션 내에서). 지침 트리는 완전히 번역됩니다 그만큼PL/PGSQL진술 구조이지만 개인SQL표현 및SQL함수에 사용 된 명령은 그렇지 않습니다 즉시 번역.
각 표현 및SQL명령에서 처음 실행됩니다
기능,토토 사이트/pgsql통역사는 준비된 실행 계획을 만듭니다 (사용SPI관리자SPI_PREPARE
andSPI_SAVEPLAN
기능).그 표현을 후속 방문 또는
준비된 계획을 재사용하십시오. 따라서 기능
많은 진술을 포함하는 조건부 코드
실행 계획이 필요할 수 있습니다.
평생 동안 실제로 사용되는 계획
데이터베이스 연결. 이것은 총계를 실질적으로 줄일 수 있습니다
실행 계획을 구문 분석하고 생성하는 데 필요한 시간
A의 진술을 위해토토 사이트/pgsql함수. 단점은 그게됩니다
특정 표현식 또는 명령의 오류를 감지 할 수 없습니다.
함수의 해당 부분이 실행 중에 도달 할 때까지.
(초기에 Trivial Syntax 오류가 감지됩니다
구문 분석 패스이지만 더 깊은 것은
실행.)
한 번토토 사이트/pgsql함수의 특정 명령에 대한 실행 계획은 데이터베이스 연결의 수명에 대한 계획을 재사용하십시오. 이것 일반적으로 성능의 승리이지만 일부는 문제 데이터베이스 스키마를 동적으로 변경하는 경우. 을 위한 예:
create function populate () 정수를 $$로 반환합니다 선언하다 - 선언 시작하다 my_function ()을 수행하십시오. 끝; $$ 언어 토토 사이트pgsql;
위의 함수를 실행하면 OID를 참조합니다.
을 위한my_function ()
에 대한 실행 계획공연진술. 나중에 떨어지면
재현my_function ()
, thepopulate ()
할 수 없습니다
찾다my_function ()
더 이상. 너
그러면 새 데이터베이스 세션을 시작하여populate ()
가 컴파일됩니다
새롭게, 다시 작동하기 전에. 이 문제를 피할 수 있습니다
사용하여함수 생성 또는 교체의 정의를 업데이트 할 때my_function
, 함수가있을 때"대체", 그 OID는 아닙니다
변경.
참고 :inPostgreSQL8.3 이상, 계획을 저장했습니다 스키마 변경이 발생할 때마다 교체됩니다 그들이 참조하는 테이블에. 이것은 하나를 제거합니다 저장된 계획의 주요 단점. 그러나 아무도 없습니다 기능 참조를위한 이러한 메커니즘, 따라서 위의 메커니즘 삭제 된 함수에 대한 참조와 관련된 예는 다음과 같습니다 여전히 유효합니다.
때문에토토 사이트/pgsql저장 이러한 방식으로 실행 계획, 직접 나타나는 SQL 명령 에서토토 사이트/pgsql함수가 있어야합니다 모든 실행에서 동일한 테이블과 열을 참조하십시오. 저것 매개 변수를 테이블 또는 열의 이름으로 사용할 수 없습니다. SQL 명령에서. 이 제한을 해결하려면 가능합니다 를 사용하여 동적 명령 구성토토 사이트/pgsql execute성명서 - 새로운 실행 계획을 세우는 대가로 모든 실행에.
또 다른 중요한 요점은 준비된 계획이 있다는 것입니다 값을 허용하도록 매개 변수화토토 사이트/pgsql한 번의 사용에서 변경되는 변수 다음에, 위에서 자세히 설명한 바와 같이. 때때로 이것은 의미합니다 계획이 생성되는 경우보다 덜 효율적이라는 특정 변수 값. 예를 들어, 고려
선택 * 사전에서 myrec에 * search_term;
여기서search_termis토토 사이트/pgsql변수. 캐시 된 계획 이 쿼리는 in index를 사용하지 않습니다Word, 플래너는 그것을 가정 할 수 없기 때문에 그만큼좋아요패턴은 좌회전됩니다 런타임에. 색인을 사용하려면 쿼리를 특정 상수좋아요패턴 제공. 이것은 또 다른 상황입니다execute새로운 계획을 강요하는 데 사용될 수 있습니다. 각 실행에 대해 생성됩니다.
레코드 변수의 변이 성 특성은 다른 것을 제시합니다 이와 관련하여 문제. 레코드 변수의 필드 표현 또는 명세서, 데이터 유형에 사용됩니다. 필드는 함수의 한 호출에서 다음으로, 각 표현식은 데이터 유형을 사용하여 계획되므로 그것은 표현이 처음 도달 할 때 존재합니다.execute이 주위를 돌리는 데 사용될 수 있습니다 필요한 경우 문제.
동일한 함수가 둘 이상의 트리거로 사용되는 경우 테이블,토토 사이트/pgsql준비 및 캐시는 그러한 각 테이블에 대해 독립적으로 계획, 즉 거기에 있습니다. 각 트리거 기능 및 테이블 조합에 대한 캐시입니다. 각 함수에 대해. 이것은 일부 문제를 완화시킵니다 다양한 데이터 유형으로; 예를 들어 트리거 함수가됩니다 라는 열로 성공적으로 작업 할 수 있어야합니다.키다른 유형이 다른 경우에도 다른 테이블에서.
마찬가지로 다형성 인수 유형을 갖는 기능에는 a가 있습니다 실제 인수의 각 조합에 대해 별도의 계획 캐시 데이터 유형 차이가 있도록 촉진 된 유형 예상치 못한 실패를 일으키지 마십시오.
계획 캐싱은 때때로 놀라운 영향을 미칠 수 있습니다 시간에 민감한 값의 해석. 예를 들어 a가 있습니다 이 두 기능의 차이점 :
함수 생성 logfunc1 (logtxt 텍스트)은 $$로 void을 반환합니다 시작하다 Logtable 값 (logtxt, 'now')에 삽입; 끝; $$ 언어 plpgsql;
및 :
함수 생성 logfunc2 (logtxt 텍스트)는 void를 $$로 반환합니다 선언하다 곡선 타임 스탬프; 시작하다 큐 타임 : = '지금'; Logtable 값 (logtxt, curtime)에 삽입; 끝; $$ 언어 plpgsql;
의 경우logfunc1
, ThePostgreSQLMain Parser는 알고 있습니다
계획을 준비 할 때삽입String'now'로 해석타임 스탬프의 대상 열logtable
그 유형. 따라서,'now'일시 상수로 변환삽입가 계획된 다음 모든 것에 사용됩니다
의 호출logfunc1
세션의 수명. 말할 것도없이, 이것은 무엇이 아닙니다
프로그래머가 원했습니다.
의 경우logfunc2
, ThePostgreSQL메인 파서가합니다
어떤 유형을 모른다'now'따라서 유형의 데이터 값을 반환합니다텍스트문자열 포함now. 다음으로 현지인에게 임무를 수행하는 동안
변하기 쉬운CURTIME, The토토 사이트/pgsql인터프리터는이 문자열을 캐스트합니다
그만큼타임 스탬프전화로 입력하십시오text_out
및TimesTamp_IN
변환 기능.
따라서 계산 된 타임 스탬프는 각 실행에 따라
프로그래머가 기대합니다.