이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다토토 커뮤니티 PostgreSQL : 문서 : 17 : 41.5. 기본 진술버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

40.5. 사설 토토 진술

이 섹션과 다음 섹션에서는에 의해 명시 적으로 이해되는 모든 진술 유형을 설명합니다.pl/pgsql. 이러한 사설 토토문 유형 중 하나로 인식되지 않은 것은 SQL 사설 토토으로 추정되며에 설명 된대로 실행하기 위해 기본 데이터베이스 엔진으로 전송됩니다.섹션 40.5.2and섹션 40.5.3.

40.5.1. 과제

값의 할당pl/pgsql변수는 다음과 같이 작성되었습니다.

변수: = | =표현;

앞에서 설명한 바와 같이, 그러한 진술의 표현은 SQL을 통해 평가됩니다select기본 데이터베이스 엔진으로 전송 된 사설 토토. 표현식은 단일 값을 산출해야합니다 (변수가 행 또는 레코드 변수 인 경우 행 값 일 수 있음). 대상 변수는 간단한 변수 (선택적으로 블록 이름으로 자격이있는), 행 또는 레코드 변수 필드 또는 간단한 변수 또는 필드 인 배열 요소 일 수 있습니다. 동일한 (=) PL/SQL 호환 대신 사용할 수 있습니다: =.

표현식의 결과 데이터 유형이 변수의 데이터 유형과 일치하지 않거나 변수에 특정 크기/정밀도가 있습니다 (좋아요char (20)), 결과 값은에 의해 암시 적으로 변환됩니다.PL/PGSQL결과 유형의 출력 기능 및 변수 유형의 입력 기능을 사용한 통역사. 결과 값의 문자열 양식이 입력 함수에 허용되지 않는 경우 입력 함수에 의해 생성 된 런타임 오류가 발생할 수 있습니다..

예 :

세금 : = 하위 토탈 * 0.06;
my_record.user_id : = 20;

40.5.2. 결과가없는 사설 토토 실행

예를 들어 행을 반환하지 않는 SQL 사설 토토의 경우삽입a반환조항, a 내 사설 토토을 실행할 수 있습니다.pl/pgsql사설 토토을 작성하는 것만으로 기능합니다.

anyPL/PGSQL사설 토토 텍스트에 나타나는 변수 이름은 매개 변수로 취급 된 다음 변수의 현재 값이 실행 시간에 매개 변수 값으로 제공됩니다. 이것은 표현에 대해 앞에서 설명한 처리와 똑같습니다. 자세한 내용은 참조섹션 40.10.1.

이러한 방식으로 SQL 사설 토토을 실행할 때pl/pgsql섹션 40.10.2.

때로는 표현식 또는를 평가하는 것이 유용합니다select쿼리 그러나 결과를 폐기하십시오. 예를 들어 부작용이 있지만 유용한 결과 값이없는 함수를 호출 할 때.pl/pgsql, 사용공연진술 :

공연쿼리;

이것은 실행쿼리결과를 버립니다. 쓰기쿼리SQL을 작성하는 것과 같은 방식select사설 토토이지만 초기 키워드를 대체selectwith공연. 을 위한with쿼리, 사용공연그런 다음 쿼리를 괄호 안에 놓습니다. (이 경우 쿼리는 한 행만 반환 할 수 있습니다.)pl/pgsql변수는 결과를 반환하지 않는 사설 토토과 마찬가지로 쿼리로 대체되며 계획은 같은 방식으로 캐시됩니다. 또한 특수 변수발견쿼리가 적어도 하나의 행을 생성 한 경우, 또는 행이 생성 된 경우 False (참조섹션 40.5.5).

참고 :글쓰기를 기대할 수 있습니다select직접이 결과를 달성 할 것이지만 현재로서는 유일하게 받아 들여진 방법은공연. 와 같은 행을 반환 할 수있는 SQL 사설 토토select,가없는 한 오류로 거부됩니다.in다음 섹션에서 논의 된 절의 조항.

예 :

create_mv ( 'cs_session_page_requests_mv', my_query); 수행

40.5.3. 단일 줄 결과로 쿼리 실행

SQL 사설 토토의 결과 단일 행 (여러 열의 가능성)을 산출하는 결과는 레코드 변수, 행 유형 변수 또는 스칼라 변수 목록에 할당 될 수 있습니다. 이것은 기본 SQL 사설 토토을 작성하고 추가를 추가하여 수행됩니다.in절. 예를 들어,

selectselect_expressions[에엄격한]대상에서 ...;
삽입 ... 반환표현[에엄격한]대상;
업데이트 ... 반환표현[에엄격한]대상;
삭제 ... 반환표현[에엄격한]대상;

여기서대상레코드 변수, 행 변수 또는 간단한 변수 및 레코드/행 필드의 쉼표로 구분 된 목록이 될 수 있습니다.pl/pgsql변수는 쿼리의 나머지 부분으로 대체되며 계획은 행을 반환하지 않는 사설 토토에 대해 위에서 설명한대로 캐시됩니다. 이것은 |select, 삽입/업데이트/삭제with반환및 ROW 세트 결과를 반환하는 유틸리티 사설 토토 (예 :설명). 을 제외하고in절, SQL 사설 토토은 외부에 기록 될 것과 동일합니다pl/pgsql.

팁 :이 해석에 주목하십시오.selectwithin|PostgreSQL'S Regement선택사설 토토, 여기서in대상은 새로 생성 된 테이블입니다. a에서 테이블을 만들고 싶다면select내부의 결과pl/pgsql함수, 구문 사용테이블 작성 ... 선택.

행 또는 변수 목록이 대상으로 사용되면 쿼리의 결과 열은 숫자 및 데이터 유형에 대한 대상 구조와 정확히 일치해야합니다. 그렇지 않으면 런타임 오류가 발생합니다. 레코드 변수가 대상이면 쿼리 결과 열의 행 유형에 자동으로 구성됩니다.

thein절은 SQL 사설 토토의 거의 모든 곳에 나타날 수 있습니다. 관습 적으로 그것은 | 목록 직전이나 바로 뒤에 쓰여졌다select_expressionsinselect사설 토토 또는 다른 사설 토토 유형에 대한 사설 토토의 끝에. 의 경우이 컨벤션을 준수하는 것이 좋습니다.pl/pgsql향후 버전에서 파서가 더 엄격 해집니다.

if엄격한에 지정되어 있지 않습니다into조항,대상쿼리로 반환 된 첫 번째 행 또는 쿼리가 행이 반환되지 않은 경우 Nulls로 설정됩니다. ("첫 번째 줄"당신이 사용하지 않는 한 잘 정의되지 않았습니다주문 by.) 첫 번째 행 후 결과 행은 폐기됩니다. 스페셜을 확인할 수 있습니다발견변수 (참조섹션 40.5.5) 행이 반환되었는지 여부를 결정하려면 :

empname = myName에서 EMP에서 MyRec에 * 선택 *;
찾을 수없는 경우
    예외 '직원 % 찾을 수 없음', MyName;
끝 If;

엄격한옵션이 지정되어 있고, 쿼리는 정확히 하나의 행을 반환해야합니다. 그렇지 않으면 런 타임 오류가보고됩니다.no_data_found(줄 없음) 또는TOO_MANY_ROWS(하나 이상). 예를 들어 오류를 잡으려는 경우 예외 블록을 사용할 수 있습니다 (예 :

시작
    Empname = myName에서 Emp에서 Strict Myrec으로 * 선택하십시오.
    예외
        그렇다면 no_data_found 일 때
            예외 '직원 % 찾을 수 없음', MyName;
        언제 너무 _many_rows
            예외를 제기하는 '직원 % 고유하지 않음', MyName;
끝;

사설 토토의 성공적인 실행엄격한항상 설정발견to true.

for삽입/업데이트/삭제with반환, pl/pgsql|엄격한지정되지 않았습니다. 와 같은 옵션이 없기 때문입니다.주문반환 해야하는 영향을받는 행을 결정하기 위해.

ifprint_strict_params함수에 대해 활성화되어 있으면 오류가 발생하면엄격한충족되지 않음,세부 사항오류 메시지의 일부에는 쿼리에 전달 된 매개 변수에 대한 정보가 포함됩니다. 당신은 변경할 수 있습니다print_strict_params설정을 통해 모든 함수 설정plpgsql.print_strict_params, 후속 기능 컴파일 만 영향을받지 만. 컴파일러 옵션을 사용하여 기능별로 활성화 할 수도 있습니다.

함수 만들기 get_userid (사용자 이름 텍스트) int를 반환합니다
$$로
#print_strict_params on
선언하다
userId int;
시작하다
    사용자를 엄격한 userID로 선택하십시오
        user.username = get_userid.username이있는 사용자로부터;
    반환 userID;
끝
$$ 언어 plpgsql;

실패시이 함수는와 같은 오류 메시지를 생성 할 수 있습니다.

오류 : 쿼리는 행이 없습니다
세부 사항 : 매개 변수 : $ 1 = 'Nosuchuser'
컨텍스트 : pl/pgsql 함수 get_userid (텍스트) SQL 문 6 행

참고 :the엄격한옵션은 Oracle PL/SQL의 동작과 일치합니다및 관련 진술.

SQL 쿼리에서 여러 결과 행을 처리 해야하는 경우를 처리하려면 참조섹션 40.6.4.

40.5.4. 동적 사설 토토 실행

종종 당신은 당신의 내부에서 동적 사설 토토을 생성하고 싶을 것입니다pl/pgsql함수, 즉 실행할 때마다 다른 테이블 또는 다른 데이터 유형이 포함되는 사설 토토.pl/pgsql의 사설 토토에 대한 계획을 캐시하려는 정상적인 시도 (섹션 40.10.2)는 그러한 시나리오에서 작동하지 않습니다. 이런 종류의 문제를 처리하려면execute진술이 제공됩니다 :

executeCommand-string[[에엄격한]대상 ] [사용표현[, ... ]];

여기서Command-string(유형의 문자열을 산출하는 표현식입니다.텍스트) 실행 할 사설 토토을 포함합니다. 선택 사항대상는 레코드 변수, 행 변수 또는 간단한 변수 및 레코드/행 필드의 쉼표로 구분 된 목록입니다. 선택 사항사용사설 토토에 삽입 할 표현식 공급 값.

대체 없음PL/PGSQL변수는 계산 된 사설 토토 문자열에서 수행됩니다. 필요한 변수 값은 구성 될 때 사설 토토 문자열에 삽입해야합니다. 또는 아래에 설명 된대로 매개 변수를 사용할 수 있습니다.

또한,execute. 대신, 사설 토토문이 실행될 때마다 사설 토토은 항상 계획됩니다. 따라서 사설 토토 문자열은 기능 내에서 동적으로 생성되어 다른 테이블과 열에서 동작을 수행 할 수 있습니다.

thein조항은 SQL 사설 토토의 결과를 반환하는 행의 결과를 지정해야합니다. 행 또는 가변 목록이 제공되면 쿼리 결과의 구조와 정확히 일치해야합니다 (레코드 변수를 사용하는 경우 결과 구조와 자동으로 일치하도록 구성). 여러 행이 반환되면 첫 번째 행만에 할당됩니다.in변수. 행이 반환되지 않으면 NULL이에 할당됩니다.in변수. 그렇지 않은 경우in조항이 지정되고 쿼리 결과가 폐기됩니다.

엄격한옵션이 제공되며, 쿼리가 정확히 하나의 행을 생성하지 않는 한 오류 가보고됩니다.

사설 토토 문자열은 매개 변수 값을 사용할 수 있으며 사설 토토에$ 1, $ 2등.이 기호는에 제공된 값을 나타냅니다.사용절. 이 방법은 종종 텍스트로 사설 토토 문자열에 데이터 값을 삽입하는 것보다 선호됩니다. 값을 텍스트와 뒤로 변환하는 런 타임 오버 헤드를 피하며 인용 또는 이스케이프 할 필요가 없기 때문에 SQL 주입 공격에 훨씬 덜 걸립니다. 예는 다음과 같습니다.

execute 'inserted_by = $ 1이고 삽입 된 mytable에서 count (*)를 선택하십시오 <= $ 2'
   c
   Checked_user 사용, Checked_date;

매개 변수 기호는 데이터 값에만 사용할 수 있습니다. 동적으로 결정된 테이블 또는 열 이름을 사용하려면 텍스트로 사설 토토 문자열에 삽입해야합니다. 예를 들어, 동적으로 선택된 테이블에 대해 이전 쿼리를 수행 해야하는 경우 다음을 수행 할 수 있습니다.

execute 'count (*)에서'
    || tabname :: regclass
    || 'inserted_by = $ 1이고 삽입 된 <= $ 2'
   c
   Checked_user 사용, Checked_date;

매개 변수 기호의 또 다른 제한은에서만 작동한다는 것입니다.select, 삽입, 업데이트삭제사설 토토. 다른 사설 토토문 유형 (일반적으로 유틸리티 사설 토토문이라고 함)에서는 데이터 값에 불과하더라도 값을 텍스트로 삽입해야합니다.

anexecute간단한 상수 사설 토토 문자열과 일부사용위의 첫 번째 예에서와 같이 매개 변수는 기능적으로 사설 토토을 직접 작성하는 것과 동일합니다pl/pgsql및 교체 허용pl/pgsql변수가 자동으로 발생합니다. 중요한 차이점은execute각 실행에 대한 사설 토토을 다시 계획하여 현재 매개 변수 값에 특정한 계획을 생성합니다. 반면PL/PGSQL그렇지 않으면 일반 계획을 작성하여 재사용 할 수 있습니다. 최상의 계획이 매개 변수 값에 크게 의존하는 상황에서 사용하는 것이 도움이 될 수 있습니다execute일반 계획이 선택되지 않았는지 긍정적으로 보장합니다.

선택현재 내부에 지원되지 않습니다execute; 대신, 평범한 실행select사설 토토 및 지정into의 일부로execute자체.

참고 :thepl/pgsql execute진술은와 관련이 없습니다메이저 토토 사이트 : 문서 : 9.4 : executeSQL 사설 토토문이 지원하는 SQL 사설 토토문PostgreSQL서버. 서버의execute사설 토토문은 직접 사용할 수 없습니다PL/PGSQL기능 (필요하지 않음).

예 40-1. 동적 쿼리의 값 인용

동적 사설 토토으로 작업 할 때는 종종 단일 따옴표의 탈출을 처리해야합니다. 기능 본문에서 고정 텍스트를 인용하는 권장 방법은 달러 인용입니다. (달러 인용을 사용하지 않는 레거시 코드가있는 경우 개요를 참조하십시오.섹션 40.11.1, 해당 코드를보다 합리적인 체계로 번역 할 때 약간의 노력을 절약 할 수 있습니다.)

구성된 쿼리에 삽입 해야하는 동적 값은 인용 문자가 포함되어 있기 때문에 신중한 처리가 필요합니다. 예제 (이것은 당신이 함수에 대해 달러 인용문을 전체적으로 사용하고 있다고 가정하므로 견적 표시를 두 배로 늘릴 필요는 없습니다) :.

실행 'TBL 세트 업데이트'
        || quote_ident (colname)
        || '='
        || quote_literal (newValue)
        || 'key ='
        || quote_literal (keyvalue);

이 예제는의 사용을 보여줍니다.quote_identandquote_literal함수 (참조PostgreSQL : 문서 : 9.4 : 스포츠 토토 함수 및 연산자). 안전을 위해 열 또는 테이블 식별자를 포함하는 표현식을 통과해야합니다QUOTE_INDEN동적 쿼리에 삽입하기 전에. 구성된 사설 토토에 문자 그대로 해야하는 값을 포함하는 표현식을 통과해야합니다QUOTE_LITERAL. 이 기능은 각각 이중 또는 단일 따옴표로 둘러싸인 입력 텍스트를 반환하기 위해 적절한 단계를 수행하고 임베디드 특수 문자가 올바르게 탈출했습니다.

때문에quote_literal라벨이 표시엄격한, null 인수로 호출되면 항상 null을 반환합니다. 위의 예에서 ifNewValue또는KeyValue무효가되었고, 전체 동적 쿼리 문자열이 널이되어 오류가 발생합니다.execute. 를 사용 하여이 문제를 피할 수 있습니다.QUOTE_NULLABLE함수는와 동일하게 작동합니다.quote_literal널 인수로 호출 할 때 문자열을 반환하는 것을 제외하고null. 예를 들어,

실행 'TBL 세트 업데이트'
        || quote_ident (colname)
        || '='
        || quote_nullable (newValue)
        || 'key ='
        || quote_nullable (keyvalue);

null 일 수있는 값을 다루는 경우 일반적으로 사용해야합니다QUOTE_NULLABLE대신quote_literal.

항상 그렇듯이 쿼리의 널 값이 의도하지 않은 결과를 제공하지 않도록주의해야합니다. 예를 들어여기서

'여기서 key ='|| quote_nullable (keyvalue)

if 성공하지 못할 것입니다.KeyValue평등 연산자를 사용한 결과이기 때문에=null 피연산자가있는 것은 항상 null입니다. NULL이 일반적인 키 가치처럼 작동하기를 원한다면 위를 다시 작성해야합니다.

31796_31859

(현재,|=, 그렇지 않으면 그렇게하지 마십시오. 보다PostgreSQL : 문서 : 9.4 : 비교 토토 핫Nulls 및에 대한 자세한 내용은뚜렷하다.)

달러 인용은 고정 텍스트를 인용하는 데만 유용합니다. 이 예제를 다음과 같이 쓰려고 시도하는 것은 매우 나쁜 생각입니다.

실행 'TBL 세트 업데이트'
        || quote_ident (colname)
        || '= $$'
        || NewValue
        || '$$ key ='
        || quote_literal (keyvalue);

이면 끊어지기 때문에NewValue포함하자$$. 동일한 반대 의견은 선택할 수있는 다른 달러 인출 구분 기호에 적용됩니다. 따라서 미리 알려지지 않은 텍스트를 안전하게 인용하려면필수usequote_literal, QUOTE_NULLABLE또는QUOTE_INDEN, 적절한.

동적 SQL 문은를 사용하여 안전하게 구성 할 수 있습니다형식함수 (참조PostgreSQL : 문서 : 9.4 : 스포츠 토토 함수 및 연산자). 예를 들어:

형식 실행 ( 'TBL 세트 %i = %l 여기서 key = %l', colname, newValue, keyValue);

the형식함수는와 함께 사용할 수 있습니다.사용절 :

형식 실행 ( 'TBL 세트 업데이트 %i = $ 1 key = $ 2', colname)
   NewValue 사용, keyValue;

이 양식은 매개 변수이기 때문에 더 효율적입니다.NewValueKeyValue텍스트로 변환되지 않습니다.

동적 사설 토토의 훨씬 더 큰 예와execute예 40-9기능 생성새 함수를 정의하도록 사설 토토.

40.5.5. 결과 상태 얻기

사설 토토의 효과를 결정하는 몇 가지 방법이 있습니다. 첫 번째 방법은를 사용하는 것입니다.진단 받기사설 토토, 양식이있는 사설 토토 :

get [현재] 진단변수= | : =항목[ , ... ];

이 사설 토토은 시스템 상태 표시기를 검색 할 수 있습니다.현재소음 단어입니다 (그러나 참조스택 진단 받기in섹션 40.6.6.1). 각항목지정된 상태 값을 식별하는 핵심 단어변수(이를 수신하기에 적합한 데이터 유형이어야 함). 현재 사용 가능한 상태 항목은에 표시됩니다.표 40-1. 결장 평등 (: =) SQL 표준 대신 사용할 수 있습니다=토큰. 예 :

진단 받기 integer_var = row_count;

표 40-1. 사용 가능한 진단 항목

이름 타입 설명
row_count 정수 가장 최근에 처리 된 행 수SQL사설 토토
result_oid OID 가장 최근에 삽입 된 마지막 행의 OIDSQL사설 토토 (AN 이후에만 유용삽입OID가있는 테이블에 사설 토토)
PG_CONTEXT 텍스트 현재 통화 스택을 설명하는 텍스트의 줄 (참조섹션 40.6.7)

사설 토토의 효과를 결정하는 두 번째 방법은 명명 된 특수 변수를 확인하는 것입니다.발견, 유형의부울. 발견각각 내에서 거짓을 시작합니다pl/pgsql함수 호출. 다음 각 유형의 진술에 의해 설정됩니다.

  • a선택사설 토토문 세트발견행이 지정된 경우 true 행이 반환되지 않으면 거짓.

  • a공연성명서 세트발견하나 이상의 행을 생성하고 폐기하는 경우, 행이 생성되지 않으면 거짓.

  • 업데이트, 삽입삭제진술 세트발견적어도 하나의 행에 영향을 미치는 경우, 행에 영향을 미치지 않으면 거짓.

  • afetch사설 토토문 세트발견행을 반환하는 경우 true 행이 반환되지 않으면 false입니다.

  • a움직임명세서 세트발견그것이 커서를 성공적으로 재배치하면 그렇지 않으면 false.

  • afor또는foreach사설 토토문 세트발견하나 이상을 반복하는 경우 true false.발견루프가 종료 될 때 이런 식으로 설정됩니다. 루프 실행 내부에서발견루프 본문 내에서 다른 문의 실행에 의해 변경 될 수 있지만 루프 문에 의해 수정되지 않았다..

  • return queryand반환 쿼리 실행진술 세트발견쿼리가 하나 이상의 행을 반환하는 경우, 행이 반환되지 않으면 false입니다.

기타PL/PGSQL진술은 상태를 변경하지 않습니다발견. 특히execute출력 변경진단 받기그러나 변경되지는 않습니다발견.

발견각각 내의 로컬 변수입니다PL/PGSQL함수; 그것에 대한 모든 변경 사항은 현재 함수에만 영향을 미칩니다.

40.5.6. 전혀 아무것도하지 않는다

때로는 아무것도하지 않는 자리 표시 자 진술이 유용합니다. 예를 들어, if/the/else 체인의 한 팔이 의도적으로 비어 있음을 나타낼 수 있습니다. 이 목적을 위해 사용하십시오.NULL진술 :

NULL;

예를 들어, 다음 두 조각의 코드 조각은 다음과 같습니다.

시작
    Y : = x / 0;
예외
    Division_by_zero가있을 때
        널;  - 오류를 무시하십시오
끝;
시작
    Y : = x / 0;
예외
    Division_By_Zero 일 때 - 오류를 무시하십시오
끝;

바람직한 맛의 문제입니다.

참고 :Oracle의 PL/SQL에서 빈 사설 토토문 목록은 허용되지 않습니다.NULL진술은필수이와 같은 상황의 경우.pl/pgsql대신 아무것도 쓸 수 있습니다.