이 섹션에서는 다음과 같은 구현 세부 사항에 대해 설명합니다. 자주 중요한토토 사이트/pgSQL사용자가 알아야 할 내용입니다.
언제토토 사이트/pgSQL준비 실행을 위한 SQL 문 또는 표현식, 모두토토 사이트/pgSQL변수 이름이 다음에 나타납니다. 명령문 또는 표현식이 매개변수 기호로 대체됩니다.$n. 그러면 변수의 현재 값이 값으로 제공됩니다. 문이나 표현식이 다음과 같을 때마다 매개변수에 대해 실행. 예를 들어 다음 함수를 고려해보세요.
CREATE FUNCTION logfunc(logtxt text) 반환 $$로 무효
    선언
        curtime 타임스탬프 := now();
    시작
        INSERT INTO 로그 테이블 VALUES(logtxt, curtime);
    끝;
$$ 언어 토토 사이트pgsql;
    그삽입문은 효과적으로 처리됩니다.
준비statement_name(텍스트, 타임스탬프) AS 로그 테이블 값에 삽입($1, $2);
각 실행 시 다음에 의해 수행됨실행현재 실제 값으로 두 가지 변수. (참고: 여기서는 기본 SQL에 대해 이야기하고 있습니다. 엔진의와이즈 토토 : 문서 : 8.3 : execute명령, 아님토토 사이트/pgSQL's실행.)
대체 메커니즘은 알려진 것과 일치하는 모든 토큰을 대체합니다. 변수 이름입니다.이것은 다음과 같은 다양한 함정을 야기합니다. 부주의하다. 예를 들어 변수 이름을 사용하는 것은 좋지 않습니다. 이는 필요한 테이블 또는 열 이름과 동일합니다. 함수 내의 쿼리에서 참조합니다. 테이블이나 열 이름이 여전히 대체될 것이라고 생각합니다. 에서 위의 예를 가정해 보겠습니다.로그테이블열 이름이 있음logtxt그리고로그타임, 그리고 우리는삽입as
INSERT INTO 로그 테이블(logtxt, logtime) VALUES(logtxt, curtime);
이것은 기본 SQL 파서에 다음과 같이 제공됩니다.
INSERT INTO 로그 테이블($1, 로그 시간) VALUES($1, $2);
다음과 같은 구문 오류가 발생합니다.
오류: "$1" 또는 그 근처에 구문 오류가 있습니다.
라인 1: INSERT INTO logtable( $1 , logtime) VALUES( $1 , $2 )
                               ^
쿼리: INSERT INTO 로그 테이블( $1 , 로그 시간) VALUES( $1 , $2 )
CONTEXT: 5행 근처 PL/PgSQL 함수 "logfunc2"의 SQL 문
    이 예는 다음과 같은 결과로 이어지기 때문에 진단하기가 매우 쉽습니다. 명백한 구문 오류입니다. 훨씬 더 나쁜 경우는 다음과 같습니다. 대체는 구문론적으로 허용됩니다. 증상은 기능의 오작동일 수 있습니다. 어떤 경우에는 사용자가 다음과 같이 썼습니다:
선언하다
        발 텍스트;
        검색_키 정수;
    시작
        ...
        FOR val IN SELECT val FROM 테이블 WHERE 키 = 검색_키 LOOP ...
    그리고 그의 테이블 항목이 모두 NULL인 것처럼 보이는 이유가 궁금했습니다. 의 물론 여기서 일어난 일은 쿼리가 다음과 같다는 것입니다.
키 = $2인 WHERE 테이블에서 $1 선택
그래서 그것은 단지 값비싼 할당 방법이었을 뿐입니다발의 현재 값을 다시 원래 값으로 되돌립니다. 각 행.
이러한 함정을 피하기 위해 일반적으로 사용되는 코딩 규칙은 다음과 같습니다. 다른 명명 규칙을 사용하십시오.토토 사이트/pgSQL테이블에 사용하는 것보다 변수가 많습니다. 그리고 열 이름. 예를 들어 모든 변수의 이름이 지정된 경우v_뭔가당신의 테이블에 아무도 없는 동안 또는 열 이름이로 시작합니다.v_당신은 꽤 안전해요.
또 다른 해결 방법은 다음에 대해 정규화된(점으로 구분된) 이름을 사용하는 것입니다. SQL 엔터티. 예를 들어 우리는 다음과 같이 안전하게 작성할 수 있었습니다. 위의 예는 다음과 같습니다.
FOR val IN SELECT table.val FROM 테이블 WHERE 키 = search_key LOOP ...
왜냐하면토토 사이트/pgSQL하지 않을 것입니다 한정된 변수의 후행 구성요소를 변수로 대체합니다. 이름. 그러나 이 솔루션이 모든 경우에 작동하는 것은 아닙니다. 이름을 한정할 수 없습니다.삽입의 예를 들어 열 이름 목록입니다. 또 다른 점은 그 기록이다. 행 변수 이름은 첫 번째 구성 요소와 일치합니다. 정규화된 이름이므로 정규화된 SQL 이름은 여전히 취약합니다. 어떤 경우에는. 그러한 경우에는 충돌하지 않는 것을 선택합니다. 변수 이름이 유일한 방법입니다.
사용할 수 있는 또 다른 기술은 라벨을 변수가 선언된 블록을 만든 다음 한정합니다. SQL 명령의 변수 이름(참조섹션 38.2). 예를 들어,
<<토토 사이트
    선언
        발 텍스트;
    시작
        ...
        업데이트 테이블 SET col = 토토 사이트.val WHERE ...
    이것은 그 자체로는 다음 문제에 대한 해결책이 아닙니다. 충돌이 발생합니다. SQL 명령의 정규화되지 않은 이름은 여전히 해석될 위험이 있습니다."틀렸어요"방법. 그러나 이는 내용을 명확히 하는 데 유용합니다. 잠재적으로 모호한 코드의 의도.
명령 문자열에서 변수 대체가 발생하지 않습니다. 에게 주어졌다실행또는 그 중 하나 변형. 이러한 변수에 다양한 값을 삽입해야 하는 경우 명령을 사용하면 다음과 같이 문자열 값을 구성하는 과정의 일부로 수행됩니다. 설명됨섹션 38.5.4.
변수 대체는 현재 다음에서만 작동합니다.선택, 삽입, 업데이트및삭제명령, 왜냐하면 기본 SQL 엔진이 이 명령에서만 매개변수 기호를 허용합니다. 사용하려면 다른 문 유형의 상수가 아닌 이름이나 값 (일반적으로 유틸리티 명령문이라고 함) 다음을 구성해야 합니다. 문자열로 된 유틸리티 설명 및실행그것.
그토토 사이트/pgSQL통역사 함수의 소스 텍스트를 구문 분석하고 내부 텍스트를 생성합니다. 함수가 처음 호출될 때 이진 명령 트리 (각 세션 내에서). 명령어 트리는 완전히 번역됩니다.토토 사이트/pgSQL문장 구조이지만 개별적임SQL표현식 및SQL함수에 사용된 명령은 다음과 같습니다. 즉시 번역되었습니다.
각 표현과SQL명령은 다음에서 처음 실행됩니다.
    함수,토토 사이트/pgSQL통역사는 준비된 실행 계획을 생성합니다(다음을 사용하여SPI관리자SPI_prepare그리고SPI_saveplan함수).해당 표현에 대한 후속 방문 또는
    명령은 준비된 계획을 재사용합니다. 따라서 함수는
    다음과 같은 많은 명령문을 포함하는 조건부 코드
    실행 계획이 필요할 수 있습니다. 준비하고 저장만 하면 됩니다.
    평생 동안 실제로 사용되는 계획
    데이터베이스 연결. 이렇게 하면 총 비용을 크게 줄일 수 있습니다.
    실행 계획을 구문 분석하고 생성하는 데 필요한 시간
    a의 진술에 대해토토 사이트/pgSQL함수. 단점은
    특정 표현식이나 명령의 오류를 감지할 수 없습니다.
    함수의 해당 부분이 실행될 때까지.
    (사소한 구문 오류는 초기 단계에서 감지됩니다.
    구문 분석 패스를 수행하지만 더 깊은 것은 감지될 때까지 감지되지 않습니다.
    실행.)
한 번토토 사이트/pgSQL이(가) 만들었습니다 함수의 특정 명령에 대한 실행 계획은 다음과 같습니다. 데이터베이스 연결 수명 동안 해당 계획을 재사용하십시오. 이 일반적으로 성능면에서 승리하지만 일부 문제가 발생할 수 있습니다. 데이터베이스 스키마를 동적으로 변경하면 문제가 발생합니다. 에 대한 예:
CREATE FUNCTION populate() 정수를 $$로 반환합니다.
선언
    -- 선언
시작
    my_function()을 수행합니다.
끝;
$$ 언어 토토 사이트pgsql;
    위 함수를 실행하면 OID를 참조하게 됩니다.
    에 대한my_function()에
    다음에 대해 작성된 실행 계획수행성명. 나중에 떨어뜨리면
    재창조my_function()그러면채우기()할 수 없습니다
    찾기my_function()더 이상. 당신
    그런 다음 새 데이터베이스 세션을 시작해야 합니다.채우기()컴파일됩니다
    다시 작동하기 전에 새로. 이 문제를 피할 수 있습니다
    사용하여함수 생성 또는 교체정의를 업데이트할 때내_기능, 함수가 다음과 같을 때부터"대체됨", OID가 아닙니다.
    변경되었습니다.
참고:에PostgreSQL8.3 이상, 저장된 계획 스키마 변경이 발생할 때마다 교체됩니다. 참조하는 모든 테이블에. 이렇게 하면 다음 중 하나가 제거됩니다. 저장된 계획의 주요 단점. 그러나 함수 참조를 위한 이러한 메커니즘, 따라서 위의 삭제된 함수에 대한 참조와 관련된 예는 다음과 같습니다. 아직 유효합니다.
왜냐하면토토 사이트/pgSQL저장 이런 식으로 실행 계획을 세우면 SQL 명령어가 직접적으로 나타나 에서토토 사이트/pgSQL함수는 반드시 모든 실행에서 동일한 테이블과 열을 참조하십시오. 그 즉, 매개변수를 테이블이나 열의 이름으로 사용할 수 없습니다. SQL 명령에서. 이 제한 사항을 해결하려면 다음을 수행하십시오. 를 사용하여 동적 명령을 구성합니다.토토 사이트/pgSQL 실행성명 — 새로운 실행 계획을 세우는 대가로 실행될 때마다.
또 다른 중요한 점은 준비된 계획이 값을 허용하도록 매개변수화됨토토 사이트/pgSQL한 번 사용으로 변경되는 변수 위에서 자세히 설명한 대로 다음으로 넘어갑니다. 때로는 이것이 의미하는 바 계획이 생성된 경우보다 효율성이 떨어집니다. 특정 변수 값. 예를 들어 다음을 고려하세요.
SELECT * INTO myrec FROM Dictionary WHERE word LIKE search_term;
어디에서검색_항은토토 사이트/pgSQL변수. 캐시된 계획 이 쿼리는 인덱스를 절대 사용하지 않습니다.단어, 플래너는 다음을 가정할 수 없으므로좋아요패턴이 왼쪽 고정됩니다 런타임에. 인덱스를 사용하려면 쿼리를 다음과 같이 계획해야 합니다. 특정 상수좋아요패턴 제공됩니다. 이것은 또 다른 상황입니다.실행새로운 계획을 강제로 실행하는 데 사용될 수 있습니다. 각 실행마다 생성됩니다.
레코드 변수의 변경 가능 특성은 또 다른 특징을 제공합니다. 이와 관련하여 문제가 있습니다. 레코드 변수의 필드가 있는 경우 표현식이나 명령문에 사용되는 데이터 유형 필드는 한 번의 함수 호출에서 다음으로 변경되어서는 안 됩니다. 다음으로, 각 표현식은 데이터 유형을 사용하여 계획되므로 표현식에 처음 도달할 때 존재합니다.실행이 문제를 해결하는 데 사용할 수 있습니다 필요할 때 문제가 발생합니다.
동일한 함수가 둘 이상의 트리거로 사용되는 경우 테이블,토토 사이트/pgSQL준비하고 각 테이블에 대해 독립적으로 계획을 캐시합니다. 각 트리거 기능과 테이블 조합에 대한 캐시입니다. 각 기능마다. 이를 통해 일부 문제가 완화됩니다. 다양한 데이터 유형으로; 예를 들어 트리거 기능은 이름이 지정된 열을 사용하여 성공적으로 작업할 수 있습니다.키우연히 다른 종류가 있더라도 다른 테이블에 있습니다.
마찬가지로, 다형성 인수 유형을 갖는 함수는 실제 인수의 각 조합에 대해 별도의 계획 캐시 호출된 유형이므로 데이터 유형이 다릅니다. 예상치 못한 오류가 발생하지 않도록 하세요.
계획 캐싱은 때때로 계획에 놀라운 영향을 미칠 수 있습니다. 시간에 민감한 값의 해석. 예를 들어 이 두 함수가 수행하는 작업의 차이점은 다음과 같습니다.
CREATE FUNCTION logfunc1(logtxt text) 반환 $$로 무효
    시작
        INSERT INTO 로그 테이블 VALUES(logtxt, 'now');
    끝;
$$ 언어 plpgsql;
    그리고:
CREATE FUNCTION logfunc2(logtxt text) 반환 $$로 무효
    선언
        curtime 타임스탬프;
    시작
        curtime := '지금';
        INSERT INTO 로그 테이블 VALUES(logtxt, curtime);
    끝;
$$ 언어 plpgsql;
    다음의 경우logfunc1, 그포스트그레SQL메인 파서는 알고 있습니다
    계획을 준비할 때삽입그 문자열'지금'해야 합니다
    다음과 같이 해석됨타임스탬프, 왜냐하면
    대상 열로그테이블다음 중
    그 유형. 따라서,'지금'될 것이다
    다음과 같은 경우 상수로 변환됩니다.삽입계획되었으며 모든 용도에 사용됩니다.
    호출logfunc1중
    세션의 수명. 말할 필요도 없이 이건 아니다.
    프로그래머가 원했어요.
다음의 경우logfunc2, 그포스트그레SQL메인 파서가 수행하는 작업
    어떤 유형인지 모르겠습니다'지금'다음과 같아야 합니다
    따라서 유형의 데이터 값을 반환합니다.텍스트문자열 포함지금. 이후 현지 임무를 수행하는 동안
    변수커타임, 그토토 사이트/pgSQL인터프리터는 이 문자열을 다음으로 변환합니다.타임스탬프다음을 호출하여 입력text_out그리고timestamp_in변환을 위한 함수.
    따라서 계산된 타임스탬프는 실행될 때마다 업데이트됩니다.
    프로그래머는 기대합니다.