| PostgreSQL 9.2.24 문서 | ||||
|---|---|---|---|---|
| 토토 커뮤니티 : 문서 : 9.2 : 표현식 | 위로 | 39장.PL/pgSQL - SQL절차적 언어 | 다음 | |
이 섹션과 다음 섹션에서 우리는 명시적으로 이해되는 명령문 유형PL/pgSQL. 다음 중 하나로 인식되지 않는 것 이러한 명령문 유형은 SQL 명령으로 추정되며 설명된 대로 실행을 위해 기본 데이터베이스 엔진으로 전송됩니다.섹션 39.5.2그리고섹션 39.5.3.
a에 값 할당PL/pgSQL변수는 다음과 같이 작성됩니다:
변수 := 표현;
앞서 설명했듯이, 그러한 진술의 표현은 SQL을 통해 평가됩니다.선택명령이 기본 데이터베이스 엔진으로 전송되었습니다. 표현은 반드시 단일 값(변수가 다음과 같은 경우 행 값일 수 있음)을 생성합니다. 행 또는 레코드 변수). 대상 변수는 간단할 수 있습니다. 변수(선택적으로 블록 이름으로 한정됨), 행이나 레코드 변수, 또는 배열의 요소 단순 변수 또는 필드.
식의 결과 데이터 유형이 일치하지 않는 경우 변수의 데이터 유형이거나 변수에 특정 유형이 있습니다. 크기/정밀도(예:문자(20)), 결과 값은에 의해 암시적으로 변환됩니다.PL/pgSQL결과를 사용하는 해석기 유형의 출력 기능과 변수 유형의 입력 기능. 이로 인해 잠재적으로 런타임 오류가 발생할 수 있습니다. 입력 함수에 의해 생성된 문자열 형식인 경우 결과 값이 입력 함수에 허용되지 않습니다.
예:
세금 := 소계 * 0.06; my_record.user_id := 20;
행을 반환하지 않는 SQL 명령의 경우, 예를 들어삽입없이돌아오는 중절, 다음 명령을 실행할 수 있습니다 a 이내PL/pgSQL함수 그냥 스포츠 토토 결과을 작성하면 됩니다.
모두PL/pgSQL변수 이름 명령 텍스트에 나타나는 것은 매개변수로 처리되며, 그러면 변수의 현재 값이 다음과 같이 제공됩니다. 런타임 시 매개변수 값. 이것은 정확히 다음과 같습니다 표현식에 대해 앞서 설명한 처리; 자세한 내용은 참조섹션 39.10.1.
이런 방식으로 SQL 명령을 실행할 때,PL/pgSQL캐시하고 재사용할 수 있습니다. 설명된 대로 스포츠 토토 결과 실행 계획섹션 39.10.2.
때로는 표현식을 평가하는 것이 유용합니다.선택질의하지만 결과를 삭제합니다. 예를 들어 부작용이 있는 함수를 호출할 때 유용한 결과 값이 없습니다. 이를 수행하려면PL/pgSQL, 다음을 사용하세요.수행성명:
수행질의;
이것은 실행됩니다질의그리고 결과를 폐기합니다. 를 쓰세요질의SQL을 작성하는 것과 같은 방식으로선택명령이지만 다음을 바꾸세요. 초기 키워드선택함께수행. 에 대한WITH쿼리, 사용수행그런 다음 괄호 안의 쿼리입니다. (이 경우 쿼리는 한 행을 반환합니다.)PL/pgSQL변수는 다음과 같이 쿼리로 대체됩니다. 결과를 반환하지 않는 명령과 계획은 다음 위치에 캐시됩니다. 같은 방식으로. 또한 특수 변수발견쿼리가 생성된 경우 true로 설정됩니다. 최소한 하나의 행, 또는 행이 생성되지 않은 경우 false(참조섹션 39.5.5).
참고:누군가는 그런 글을 기대할 수도 있습니다선택직접적으로 이 일을 성취할 것입니다 그러나 현재 이를 수행하는 유일한 방법은 다음과 같습니다.수행. 다음을 수행할 수 있는 SQL 명령 다음과 같은 행을 반환합니다.선택, 그럴 거예요 다음이 없으면 오류로 거부됩니다.INTO다음에 설명된 절 섹션.
예:
create_mv('cs_session_page_requests_mv', my_query) 수행;
  단일 행을 생성하는 SQL 명령의 결과(아마도 여러 열)을 레코드 변수에 할당할 수 있습니다. 행 유형 변수 또는 스칼라 변수 목록. 이는 다음에 의해 수행됩니다. 기본 SQL 명령을 작성하고INTO절. 예를 들어,
선택select_expressionsINTO [STRICT] 대상발신 ...; 삽입... 반환 중표현INTO [STRICT] 대상; 업데이트 ... 복귀 중표현INTO [STRICT] 대상; 삭제 ... 복귀 중표현INTO [STRICT] 대상;
어디에서대상기록이 될 수 있습니다 변수, 행 변수 또는 쉼표로 구분된 단순 목록 변수 및 레코드/행 필드.PL/pgSQL변수가 대체됩니다 나머지 쿼리에 추가하면 다음과 같이 계획이 캐시됩니다. 행을 반환하지 않는 명령에 대해서는 위에 설명되어 있습니다. 이 에서 일함선택, 삽입/업데이트/삭제함께돌아오는 중및 유틸리티 명령 행 집합 결과를 반환합니다(예:설명). 제외하고INTO절, SQL 명령은 그것과 동일합니다 외부에 기록될 것입니다PL/pgSQL.
팁:이 해석은선택함께INTO입니다 와는 아주 다릅니다포스트그레SQL의 단골선택스포츠 토토 결과, 여기서INTO대상은 새로 생성된 테이블입니다. 당신이 a에서 테이블을 만들고 싶습니다.선택a 내부 결과PL/pgSQL함수, 구문을 사용하세요선택으로 테이블 생성 ....
행 또는 변수 목록이 대상으로 사용되는 경우 쿼리의 결과 열은 대상의 구조와 정확하게 일치해야 합니다. 그렇지 않으면 런타임 오류가 발생합니다. 레코드 변수가 대상이면 자동으로 쿼리 결과의 행 유형으로 자체 구성 열.
그INTO절은 거의 나타날 수 있습니다. SQL 명령의 어느 곳에서나. 관례적으로 다음 중 하나를 작성합니다. 목록 바로 앞 또는 바로 뒤select_expressions에선택스포츠 토토 결과 또는 스포츠 토토 결과 끝에 다른 스포츠 토토 결과 유형. 이것을 따르는 것이 좋습니다 경우에 대한 규칙PL/pgSQL파서는 앞으로 더욱 엄격해집니다 버전.
만약STRICT다음에 지정되지 않았습니다.INTO절, 그럼대상첫 번째 행으로 설정됩니다 쿼리에 의해 반환되거나 쿼리가 no를 반환한 경우 null로 반환됩니다. 행. (참고하세요"첫 번째 행"이다 사용하지 않는 한 잘 정의되지 않음주문 으로.) 첫 번째 행 이후의 모든 결과 행은 삭제됩니다. 특집을 확인하실 수 있습니다발견변수(참조섹션 39.5.5) 행이 반환되었는지 확인하려면 다음을 수행하세요.
SELECT * INTO myrec FROM emp WHERE empname = myname;
발견되지 않은 경우
    RAISE EXEPTION '직원 %를 찾을 수 없음', myname;
종료하면;
    만약에STRICT옵션이 지정되었습니다. 쿼리는 정확히 하나의 행을 반환해야 합니다. 그렇지 않으면 런타임 오류가 발생합니다. 다음 중 하나를 보고해야 합니다.NO_DATA_FOUND(아니요 행) 또는TOO_MANY_ROWS(하나 이상 행). 다음을 포착하려면 예외 블록을 사용할 수 있습니다. 오류입니다. 예를 들면 다음과 같습니다.
시작
    SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
    예외
        NO_DATA_발견된 시점
            RAISE EXEPTION '직원 %를 찾을 수 없음', myname;
        다음에는 TOO_MANY_ROWS개일 때
            RAISE EXEPTION '직원 %가 고유하지 않음', myname;
끝;
    다음 명령을 성공적으로 실행했습니다.엄격항상 설정발견참으로.
용삽입/업데이트/삭제함께돌아오는 중, PL/pgSQL다음 이상의 오류를 보고합니다. 1개의 행이 반환된 경우에도 마찬가지입니다.STRICT이다 지정되지 않았습니다. 와 같은 옵션이 없기 때문입니다.주문 기준그것으로 무엇을 결정할 것인가 영향을 받은 행이 반환되어야 합니다.
참고:그STRICT옵션 Oracle PL/SQL의 동작과 일치합니다.선택및 관련 진술.
여러 결과를 처리해야 하는 경우를 처리하려면 SQL 쿼리의 행은 다음을 참조하세요.섹션 39.6.4.
종종 내부에서 동적 스포츠 토토 결과을 생성하고 싶을 때가 있습니다 당신의PL/pgSQL함수, 그 즉, 다른 테이블이나 다른 테이블을 포함하는 스포츠 토토 결과입니다. 실행될 때마다 데이터 유형이 표시됩니다.PL/pgSQL의 정상적인 캐시 계획 시도 명령의 경우(에서 설명한 대로)섹션 39.10.2)는 이러한 시나리오에서는 작동하지 않습니다. 이를 처리하려면 일종의 문제입니다.실행문장 제공됩니다:
실행스포츠 토토 결과어-문자열 [INTO [STRICT] 대상 ] [사용 중표현 [, ... ] ];
어디에서스포츠 토토 결과어-문자열은 문자열을 생성하는 표현식(유형)텍스트) 실행할 명령이 포함되어 있습니다. 는 선택사항대상기록입니다 변수, 행 변수 또는 쉼표로 구분된 단순 목록 변수 및 레코드/행 필드에 명령이 저장됩니다. 선택사항사용 중식은 삽입할 값을 제공합니다. 명령에 들어갑니다.
대체 없음PL/pgSQL변수는 계산된 명령 문자열에서 수행됩니다. 필수 변수 값은 명령 문자열에 그대로 삽입되어야 합니다. 건설; 또는 아래 설명된 대로 매개변수를 사용할 수 있습니다.
또한 다음을 통해 실행되는 명령에 대한 계획 캐싱이 없습니다.실행. 대신 명령은 다음과 같습니다. 명령문이 실행될 때마다 항상 계획됩니다. 따라서 명령은 문자열은 함수 내에서 동적으로 생성될 수 있습니다. 다양한 테이블과 열에 대해 작업을 수행합니다.
그INTO절은 행을 반환하는 SQL 명령의 결과가 할당되어야 합니다. 만약에 행 또는 변수 목록이 제공되면 정확히 일치해야 합니다. 쿼리 결과의 구조(레코드 변수가 사용되면 결과 구조와 일치하도록 자체 구성됩니다. 자동으로). 여러 행이 반환되는 경우 첫 번째 행만 에 할당됩니다.INTO변수. 반환된 행이 없으면 NULL이에 할당됩니다.INTO변수. 그렇지 않은 경우INTO절이 지정되면 쿼리 결과는 다음과 같습니다. 폐기되었습니다.
만약에STRICT옵션이 주어지면 쿼리가 정확히 하나를 생성하지 않는 한 오류가 보고됩니다. 행.
명령 문자열은 매개변수 값을 사용할 수 있습니다. 명령에서 다음과 같이 참조됩니다.$1, $2등. 이 기호는 값을 나타냅니다. 에서 제공됨사용 중절. 이 데이터 값을 삽입하는 것보다 방법이 더 선호되는 경우가 많습니다. 명령 문자열을 텍스트로: 런타임 오버헤드를 방지합니다. 값을 텍스트로 변환하거나 다시 변환하면 훨씬 적습니다. 필요하지 않기 때문에 SQL 주입 공격에 취약합니다. 인용하거나 탈출합니다. 예는 다음과 같습니다:
EXECUTE 'SELECT count(*) FROM mytable WHERE 삽입된_by = $1 AND 삽입된 <= $2' INTO c 확인된_사용자, 확인된_날짜 사용;
매개변수 기호는 데이터 값에만 사용할 수 있습니다. — 동적으로 결정된 테이블이나 열을 사용하려는 경우 이름을 명령 문자열에 텍스트로 삽입해야 합니다. 예를 들어 이전 쿼리가 동적으로 선택된 테이블에서는 다음을 수행할 수 있습니다.
'SELECT count(*) FROM' 실행
    || 탭 이름::regclass
    || ' 삽입된_by = $1 AND 삽입된 <= $2'
   INTO c
   확인된_사용자, 확인된_날짜 사용;
    매개변수 기호에 대한 또 다른 제한사항은 일하다선택, 삽입, 업데이트및삭제명령. 다른 진술에서는 유형(일반적으로 유틸리티 문이라고 함)에는 다음을 삽입해야 합니다. 데이터 값일지라도 텍스트로 값을 표시합니다.
안실행간단한 상수 포함 스포츠 토토 결과 문자열 및 일부사용 중매개변수는 위의 첫 번째 예와 같이 기능적으로 명령을 직접 작성하는 것과 같습니다.PL/pgSQL및 교체 허용PL/pgSQL변수가 발생합니다 자동으로. 중요한 차이점은 다음과 같습니다.실행각각의 명령을 다시 계획할 것입니다. 실행, 현재에 특정한 계획 생성 매개변수 값; 반면PL/pgSQL그렇지 않으면 일반을 생성할 수 있습니다. 재사용을 위해 계획하고 캐시합니다. 최선의 계획이 필요한 상황에서는 매개변수 값에 따라 크게 달라지므로 다음을 수행하는 것이 도움이 될 수 있습니다. 사용실행적극적으로 보장하기 위해 일반 계획이 선택되지 않았습니다.
선택현재는 아님 이내 지원됨실행; 대신에 일반 실행선택스포츠 토토 결과 및 지정하다INTO의 일부로실행그 자체.
참고:그PL/pgSQL 실행문은 다음과 관련이 없습니다토토 캔 : 문서 : 9.2 : executeSQL문 에서 지원함PostgreSQL서버. 서버의실행문은 사용할 수 없습니다 바로 안에PL/pgSQL함수(필요하지 않음).
예 39-1. 동적 값 인용 쿼리
동적 명령으로 작업할 때 종종 다음을 수행해야 합니다. 작은따옴표의 이스케이프를 처리합니다. 권장되는 방법 함수 본문에서 고정 텍스트를 인용하는 것은 달러 인용입니다. (달러 인용을 사용하지 않는 레거시 코드가 있는 경우, 개요를 참조하세요.섹션 39.11.1, 번역할 때 수고를 덜 수 있습니다. 더 합리적인 방식으로 코드를 작성했습니다.)
에 삽입될 동적 값 생성된 쿼리는 주의 깊게 처리해야 합니다. 자체에는 따옴표 문자가 포함되어 있습니다. 예(이것은 가정합니다. 함수에 달러 인용을 사용하고 있음을 전체이므로 따옴표를 두 배로 늘릴 필요가 없습니다):
'UPDATE TBL SET' 실행
        || quote_ident(열이름)
        || ' = '
        || quote_literal(새 값)
        || ' WHERE 키 = '
        || quote_literal(키값);
      이 예는 다음의 사용을 보여줍니다.quote_ident그리고quote_literal함수(참조섹션 9.4). 안전을 위해,
      열 또는 테이블 식별자를 포함하는 표현식은 다음과 같아야 합니다.
      통과했습니다quote_ident동적 쿼리에 삽입하기 전. 다음을 포함하는 표현식
      생성된 문자열에서 리터럴 문자열이어야 하는 값
      명령이 전달되어야 합니다.quote_literal. 이러한 기능은
      이중으로 묶인 입력 텍스트를 반환하는 적절한 단계
      또는 특수 문자가 포함된 작은따옴표
      문자가 올바르게 이스케이프되었습니다.
왜냐하면quote_literal이다
      라벨이 지정됨STRICT, 항상 그렇습니다
      null 인수로 호출하면 null을 반환합니다. 위에서
      예를 들어, 만약새값또는키값null, 전체 동적 쿼리
      문자열이 null이 되어 오류가 발생합니다.실행. 다음을 사용하면 이 문제를 피할 수 있습니다.quote_nullable함수,
      이는 다음과 동일하게 작동합니다.quote_literal단, 호출할 때는 제외
      null 인수는 문자열을 반환합니다.NULL. 예를 들어,
'UPDATE TBL SET' 실행'
        || quote_ident(열이름)
        || ' = '
        || quote_nullable(새 값)
        || ' WHERE 키 = '
        || quote_nullable(키값);
      널일 수 있는 값을 처리하는 경우,
      일반적으로 사용해야 합니다quote_nullable대신quote_literal.
항상 그렇듯이 null 값이 발생하지 않도록 주의해야 합니다. 쿼리에서 의도하지 않은 결과를 제공하지 마세요. 예를 들어어디에서절
'WHERE 키 = ' || quote_nullable(키값)
다음과 같은 경우에는 결코 성공하지 못할 것입니다키값이다 null, 같음 연산자를 사용한 결과입니다.=널 피연산자를 사용하면 항상 널. null이 일반 키 값처럼 작동하도록 하려면 다음을 수행하세요. 위의 내용을 다음과 같이 다시 작성해야 합니다.
'키가 다음과 구별되지 않는 곳' || quote_nullable(키값)
(현재,다음과 다르지 않습니다다음보다 훨씬 덜 효율적으로 처리됩니다.=, 꼭 필요한 경우가 아니면 이 작업을 수행하지 마세요. 참조PostgreSQL : 문서 : 9.2 : 토토 핫 연산자더 보기 null에 대한 정보 및IS 고유.)
달러 인용은 고정 인용에만 유용합니다. 텍스트. 이런 글을 쓰려고 하는 것은 매우 나쁜 생각일 것이다 예를 들면 다음과 같습니다:
'UPDATE TBL SET' 실행
        || quote_ident(열이름)
        || ' = $$'
        || 새로운 값
        || '$$ WHERE 키 = '
        || quote_literal(키값);
      왜냐하면 다음의 내용이 깨지면 깨질 것이기 때문입니다.새값우연히 포함된$$. 어떤 경우에도 동일한 반대 의견이 적용됩니다.
      당신이 선택할 수 있는 다른 달러 인용 구분 기호. 그러니 안전하게
      미리 알려지지 않은 텍스트를 인용해 보세요.반드시사용quote_literal, quote_nullable또는quote_ident적절하게.
동적 SQL 문도 안전하게 구성할 수 있습니다.
      를 사용하여형식함수(참조PostgreSQL : 문서 : 9.2 : 스포츠 토토 결과 함수 및 연산자). 에 대한
      예:
EXECUTE 형식('UPDATE tbl SET %I = %L WHERE 키 = %L', 열 이름, 새 값, 키 값);
      그형식함수는 다음과 같습니다.
      와 함께 사용됨사용 중절:
EXECUTE 형식('UPDATE tbl SET %I = $1 WHERE 키 = $2', 열 이름)
   새로운 값, 키값 사용;
      이 형식은 매개변수 때문에 더 효율적입니다.새값그리고키값텍스트로 변환되지 않습니다.
동적 스포츠 토토 결과의 훨씬 더 큰 예이며실행다음에서 볼 수 있음예 39-8, 다음을 빌드하고 실행합니다.만들기 기능새 기능을 정의하는 스포츠 토토 결과입니다.
스포츠 토토 결과의 효과를 결정하는 방법에는 여러 가지가 있습니다. 첫 번째 방법은GET 진단명령, 형식은 다음과 같습니다.
GET [현재] 진단변수 = 항목 [ , ... ];
이 스포츠 토토 결과은 시스템 상태 표시기를 검색할 수 있습니다. 각각항목키워드입니다 지정된 상태에 할당될 상태 값 식별 변수(수신할 올바른 데이터 유형이어야 함) 그것). 현재 사용 가능한 상태 항목은 다음과 같습니다.ROW_COUNT, 처리된 행 수 마지막SQL명령이 다음으로 전송되었습니다.SQL엔진 및RESULT_OID, 다음에 의해 삽입된 마지막 행의 OID 가장 최근SQL스포츠 토토 결과. 참고하세요RESULT_OID유용할 뿐이에요 이후삽입테이블에 스포츠 토토 결과 OID를 포함합니다.
예:
진단 받기 정수_var = ROW_COUNT;
명령의 효과를 결정하는 두 번째 방법은 이름이 지정된 특수 변수를 확인하려면발견, 유형은부울. 발견시작하다 각각 거짓PL/pgSQL함수 호출. 다음 각 유형에 의해 설정됩니다. 진술:
A 선택문 세트발견행이 할당되면 true, 행이 반환되지 않으면 false입니다.
A 수행문 세트발견생성하면 true(그리고 삭제) 하나 이상의 행, 행이 없으면 false 생산되었습니다.
업데이트, 삽입및삭제문 세트발견다음에 있는 경우 true 최소한 하나의 행이 영향을 받습니다. 행이 영향을 받지 않으면 false입니다.
A 가져오기문 세트발견행을 반환하면 true, 행이 반환되지 않으면 false입니다.
A 이동문 세트발견성공적으로 성공하면 true 커서 위치를 변경하고, 그렇지 않으면 false입니다.
A for또는FOREACH문 세트발견한 번 이상 반복되면 true, 그렇지 않으면 거짓입니다.발견이렇게 설정되었습니다 루프가 종료될 때; 루프 실행 내부에서,발견루프에 의해 수정되지 않음 명령문의 실행에 따라 변경될 수 있지만 루프 본문 내의 다른 문.
쿼리 반환그리고반환 쿼리 실행문 세트발견쿼리가 다음 시간에 반환되면 true입니다. 행이 하나 이상 있고, 행이 반환되지 않으면 false입니다.
기타PL/pgSQL문장 상태를 변경하지 마십시오.발견. 참고 특히 그실행변경 출력진단 받기, 하지만 그렇습니다 변경하지 않음발견.
발견은(는) 다음의 지역 변수입니다. 각각PL/pgSQL함수; 어떤 변경 사항은 현재 기능에만 영향을 미칩니다.
가끔 아무 작업도 수행하지 않는 자리 표시자 문은 유용합니다. 예를 들어, 이는 다음 팔 중 하나를 나타낼 수 있습니다. if/then/else 체인이 의도적으로 비어 있습니다. 이를 위해 다음을 사용하십시오.NULL성명:
NULL;
예를 들어, 다음 두 코드 조각은 다음과 같습니다. 이에 상응하는 것:
시작
    y := x / 0;
예외
    WHEN Division_by_zero THEN
        NULL;  -- 오류를 무시하세요
끝;
    시작
    y := x / 0;
예외
    WHEN Division_by_zero THEN -- 오류를 무시합니다.
끝;
    어느 것이 더 좋은지는 취향의 문제입니다.
참고:오라클의 PL/SQL에서 빈 명령문 목록 허용되지 않으므로NULL문장은필수이러한 상황의 경우 이것으로.PL/pgSQL허용합니다 대신 아무것도 쓰지 마세요.