43.7. 커서#

전체 쿼리를 한 번에 실행하는 대신 다음을 설정할 수 있습니다.커서쿼리를 캡슐화한 다음 쿼리 결과를 한 번에 몇 행씩 읽습니다. 이렇게 하는 한 가지 이유는 결과에 많은 수의 행이 포함되어 있을 때 메모리 오버런을 방지하기 위해서입니다. (단,PL/pgSQL사용자는 일반적으로 그것에 대해 걱정할 필요가 없습니다. 왜냐하면for루프는 메모리 문제를 피하기 위해 자동으로 내부적으로 커서를 사용합니다.) 더 흥미로운 사용법은 함수가 생성한 커서에 대한 참조를 반환하여 호출자가 행을 읽을 수 있도록 하는 것입니다. 이는 함수에서 큰 행 집합을 반환하는 효율적인 방법을 제공합니다.

43.7.1. 커서 변수 선언#

다음 커서에 대한 모든 접근PL/pgSQL항상 특수 데이터 유형인 커서 변수를 통과합니다.반환자. 커서 변수를 생성하는 한 가지 방법은 해당 변수를 유형의 변수로 선언하는 것입니다.반환자. 또 다른 방법은 커서 선언 구문을 사용하는 것입니다. 일반적으로 다음과 같습니다.

이름 [ [아니요] 스크롤] 커서 [ ( 인수 ) ] FOR질의;

(for다음으로 대체 가능ISfor오라클호환성.) If스크롤이 지정되면 커서는 뒤로 스크롤할 수 있습니다. 만일스크롤 없음이 지정되면 역방향 가져오기가 거부됩니다. 두 사양이 모두 나타나지 않으면 역방향 가져오기가 허용되는지 여부는 쿼리에 따라 다릅니다.인수(지정된 경우)은 쉼표로 구분된 쌍 목록입니다.이름 데이터 유형주어진 쿼리에서 매개변수 값으로 대체될 이름을 정의합니다. 이러한 이름을 대체할 실제 값은 나중에 커서가 열릴 때 지정됩니다.

일부 예:

선언하다
    curs1 재귀사자;
    curs2 선택을 위한 커서 * tenk1에서;
    curs3 CURSOR(키 정수) FOR SELECT * FROM tenk1 WHERE Unique1 = 키;

이 변수 세 개 모두 데이터 유형이 있습니다.반환자, 그러나 첫 번째는 모든 쿼리에 사용할 수 있지만 두 번째는 이미 완전히 지정된 쿼리를 가지고 있습니다.바운드그리고 마지막에는 매개변수화된 쿼리가 바인딩되어 있습니다. (커서가 열리면 정수 매개변수 값으로 대체됩니다.) 변수curs1그렇다고 합니다언바운드특정 쿼리에 바인딩되지 않기 때문입니다.

스크롤커서의 쿼리가 다음을 사용하는 경우 옵션을 사용할 수 없습니다.업데이트/공유용. 또한 사용하는 것이 가장 좋습니다스크롤 없음휘발성 함수와 관련된 쿼리를 사용합니다. 의 구현스크롤쿼리의 출력을 다시 읽으면 휘발성 함수토토는 수행할 수 없는 일관된 결과가 제공된다고 가정합니다.

43.7.2. 커서 열기#

커서를 사용하여 행을 검색하려면 먼저 커서를 사용해야 합니다.열림. (This is the equivalent action to the SQL command커서 선언.) PL/pgSQL세 가지 형태의가 있습니다.열기문 중 두 개는 바인딩되지 않은 커서 변수를 사용하고 세 번째는 바인딩된 커서 변수를 사용합니다.

참고

바운드 커서 변수는 명시적으로 커서를 열지 않고도 다음을 통해 사용할 수 있습니다.for설명된 문섹션 43.7.4. 갑for루프는 커서를 열고 루프가 완료되면 다시 닫습니다.

커서를 열면 a라는 서버 내부 데이터 구조가 생성됩니다.포털, 커서 쿼리의 실행 상태를 보유합니다. 포털에는 포털이 존재하는 동안 세션 내에서 고유해야 하는 이름이 있습니다. 기본적으로,PL/pgSQL생성되는 각 포털에 고유한 이름을 할당합니다. 그러나 null이 아닌 문자열 값을 커서 변수에 할당하면 해당 문자열이 포털 이름으로 사용됩니다. 이 기능은 다음에 설명된 대로 사용할 수 있습니다.섹션 43.7.3.5.

43.7.2.1. 다음을 위해 열려 있음 질의 #

열기unbound_cursorvar [ [아니요] 스크롤] FOR질의;

커서 변수가 열리고 실행할 지정된 쿼리가 제공됩니다. 커서는 이미 열려 있을 수 없으며 바인딩되지 않은 커서 변수(즉, 간단한반환자변수). 쿼리는 다음과 같아야 합니다.선택또는 행을 반환하는 다른 것(예:설명). 쿼리는 다른 SQL 명령과 동일한 방식으로 처리됩니다.PL/pgSQL: PL/pgSQL변수 이름이 대체되고 재사용이 가능하도록 쿼리 계획이 캐시됩니다. 때PL/pgSQL변수가 커서 쿼리로 대체되고 대체된 값은 해당 시점의 값입니다.열기; 이후에 변수를 변경해도 커서의 동작에는 영향을 주지 않습니다. 그만큼스크롤그리고스크롤 없음옵션은 바인딩된 커서와 동일한 의미를 갖습니다.

예:

OPEN curs1 FOR SELECT * FROM foo WHERE 키 = mykey;

43.7.2.2. 실행 가능 #

열기unbound_cursorvar [ [아니요] 스크롤] 실행용query_string
                                     [사용 중표현 [, ... ] ];

커서 변수가 열리고 실행할 지정된 쿼리가 제공됩니다. 커서는 이미 열려 있을 수 없으며 바인딩되지 않은 커서 변수(즉, 간단한반환자변수). 쿼리는와 같은 방식으로 문자열 표현식으로 지정됩니다.실행명령. 평소와 같이 이는 유연성을 제공하므로 실행마다 쿼리 계획이 달라질 수 있습니다(참조섹션 43.11.2), 이는 또한 명령 문자열토토 변수 대체가 수행되지 않음을 의미합니다. 마찬가지로실행, 매개변수 값은 다음을 통해 동적 명령에 삽입될 수 있습니다.형식()그리고사용 중.스크롤그리고스크롤 없음옵션은 바인딩된 커서와 동일한 의미를 갖습니다.

예:

실행을 위해 curs1 열기 형식('SELECT * FROM %I WHERE col1 = $1',tabname) 키값을 사용함;

이 예에서는 테이블 이름이 다음을 통해 쿼리에 삽입됩니다.형식(). 에 대한 비교 값col1a를 통해 삽입됩니다.사용 중매개변수이므로 인용할 필요가 없습니다.

43.7.2.3. 바운드 커서 열기#

열기bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ];

이 형식은열기은 선언 시 쿼리가 바인딩된 커서 변수를 여는 데 사용됩니다. 커서는 이미 열려 있을 수 없습니다. 실제 인수 값 표현식 목록은 커서가 인수를 사용하도록 선언된 경우에만 나타나야 합니다. 이 값은 쿼리에서 대체됩니다.

바운드 커서에 대한 쿼리 계획은 항상 캐시 가능한 것으로 간주됩니다. 해당하는 것은 없습니다실행이 경우. 참고하세요스크롤그리고스크롤 없음다음에 지정할 수 없습니다.열기, 커서의 스크롤 동작이 이미 결정되었기 때문입니다.

인수 값은 다음 중 하나를 사용하여 전달될 수 있습니다.위치또는이름이표기법. 위치 표기법에서는 모든 인수가 순서대로 지정됩니다. 명명된 표기법에서 각 인수의 이름은 다음을 사용하여 지정됩니다.:=인수 표현식과 분리합니다. 다음에 설명된 함수 호출과 유사합니다.토토 사이트 추천 : 문서 : 16 : 4.3. 함수 호출, 위치 표기법과 명명 표기법을 혼합하는 것도 허용됩니다.

예(위의 커서 선언 예를 사용함):

OPEN curs2;
OPEN curs3(42);
OPEN curs3(key := 42);

바인딩된 커서의 쿼리에서 변수 대체가 이루어지기 때문에 실제로 커서에 값을 전달하는 두 가지 방법이 있습니다: 명시적인 인수를 사용하는 것열기또는 암시적으로 a를 참조하여PL/pgSQL쿼리의 변수입니다. 그러나 바인딩된 커서가 선언되기 전에 선언된 변수만 해당 커서로 대체됩니다. 두 경우 모두 전달될 값은열기. 예를 들어, 다음과 같은 효과를 얻는 또 다른 방법은curs3위의 예는

선언하다
    키 정수;
    curs4 선택을 위한 커서 * tenk1에서 고유1 = 키;
시작
    키 := 42;
    OPEN curs4;

43.7.3. 커서 사용#

커서가 열리면 여기에 설명된 명령문으로 조작할 수 있습니다.

이러한 조작은 시작하기 위해 커서를 연 동일한 함수에서 발생할 필요가 없습니다. 다음을 반환할 수 있습니다.반환자함수에서 값을 꺼내고 호출자가 커서에서 작업하도록 합니다. (내부적으로, a반환자값은 단순히 커서에 대한 활성 쿼리가 포함된 포털의 문자열 이름입니다. 이 이름은 다른 사람에게 전달되거나 할당될 수 있습니다.반환자포털을 방해하지 않고 변수 등을 처리합니다.)

모든 포털은 트랜잭션 종료 시 암시적으로 닫힙니다. 그러므로 a반환자값은 트랜잭션이 끝날 때까지만 열린 커서를 참조하는 데 사용할 수 있습니다.

43.7.3.1. 가져오기 #

가져오기 [ 방향보낸 사람 | 안으로] 커서INTO대상;

가져오기다음 행(지시된 방향으로)을 커서에서 대상으로 검색합니다. 이는 행 변수, 레코드 변수 또는 쉼표로 구분된 단순 변수 목록일 수 있습니다.선택. 적합한 행이 없으면 대상은 NULL로 설정됩니다. 마찬가지로선택, 특수 변수발견행을 얻었는지 여부를 확인할 수 있습니다. 행을 얻지 못한 경우 커서는 이동 방향에 따라 마지막 행 뒤 또는 첫 번째 행 앞에 위치합니다.

방향절은 SQL에서 허용되는 모든 변형이 될 수 있습니다.가져오기두 개 이상의 행을 가져올 수 있는 명령을 제외한 명령; 즉, 그럴 수 있습니다.다음, 이전, 첫 번째, 마지막, 절대 개수, 상대적 개수, 앞으로, 또는뒤로. 생략방향지정과 동일다음. a를 사용하는 양식토토개수, 그개수모든 정수 값 표현식이 될 수 있습니다(SQL과 달리가져오기정수 상수만 허용하는 명령).방향뒤로 이동해야 하는 값은 커서가 선언되거나 열리지 않으면 실패할 가능성이 높습니다.스크롤옵션.

커서다음의 이름이어야 합니다.반환자열린 커서 포털을 참조하는 변수입니다.

예:

curs1 INTO rowvar를 가져오세요;
curs2를 foo, bar, baz로 가져옵니다.
curs3에서 마지막으로 x, y로 가져옵니다.
curs4에서 x로 상대 -2를 가져옵니다.

43.7.3.2. 이동 #

이동 [ 방향보낸 사람 | 안으로] 커서;

이동데이터를 검색하지 않고 커서의 위치를 변경합니다.이동다음과 같이 작동합니다가져오기명령. 단, 커서 위치만 변경하고 이동된 행은 반환하지 않습니다. 그만큼방향절은 SQL에서 허용되는 모든 변형이 될 수 있습니다.가져오기명령(둘 이상의 행을 가져올 수 있는 명령 포함) 커서는 그러한 마지막 행에 위치합니다. (단, 다음의 경우방향절은 단순히 a개수키워드가 없는 표현식은 다음에서 더 이상 사용되지 않습니다.PL/pgSQL. 해당 구문은 다음과 같은 경우에 모호합니다.방향절이 모두 생략되었으므로 다음과 같은 경우 실패할 수 있습니다.개수은 상수가 아닙니다.) 마찬가지로선택, 특수 변수발견이동할 행이 있는지 확인할 수 있습니다. 해당 행이 없으면 커서는 이동 방향에 따라 마지막 행 뒤 또는 첫 번째 행 앞에 위치합니다.

예:

MOVE 커서1;
curs3에서 마지막으로 이동;
curs4에서 상대 -2를 이동합니다.
curs4에서 앞으로 2로 이동;

43.7.3.3. 현재 위치 업데이트/삭제 #

업데이트테이블설정 ... 현재 위치커서;
다음에서 삭제:테이블현재 위치커서;

커서가 테이블 행에 위치하면 커서를 사용하여 행을 식별하여 해당 행을 업데이트하거나 삭제할 수 있습니다. 커서의 쿼리가 무엇인지에 대한 제한이 있으며(특히 그룹화 없음) 사용하는 것이 가장 좋습니다.업데이트용커서에. 자세한 내용은 다음을 참조하세요.선언참조 페이지.

예:

Foo SET dataval 업데이트 = myval 현재 curs1의 위치;

43.7.3.4. 닫기 #

닫기커서;

닫기열린 커서 아래에 있는 포털을 닫습니다. 이는 트랜잭션이 끝나기 전에 리소스를 해제하거나 커서 변수를 해제하여 다시 열 때 사용할 수 있습니다.

예:

curs1 닫기;

43.7.3.5. 커서 반환#

PL/pgSQL함수는 호출자에게 커서를 반환할 수 있습니다. 이는 특히 매우 큰 결과 집합의 경우 여러 행이나 열을 반환하는 데 유용합니다. 이를 수행하기 위해 함수는 커서를 열고 커서 이름을 호출자에게 반환합니다(또는 단순히 호출자가 지정하거나 호출자에게 알려진 포털 이름을 사용하여 커서를 엽니다). 그러면 호출자는 커서에서 행을 가져올 수 있습니다. 커서는 호출자가 닫을 수 있으며, 트랜잭션이 닫힐 때 자동으로 닫힙니다.

커서에 사용되는 포털 이름은 프로그래머가 지정하거나 자동으로 생성될 수 있습니다. 포털 이름을 지정하려면 간단히반환자열기 전에 변수입니다. 의 문자열 값반환자변수는 다음에 의해 사용됩니다열기기본 포털의 이름입니다. 그러나 만약에반환자변수의 값이 null(기본값)인 경우열기기존 포털과 충돌하지 않는 이름을 자동으로 생성하여 해당 포털에 할당합니다.반환자변수.

참고

이전포스트그레SQL16, 바인딩된 커서 변수는 null로 남겨두지 않고 자체 이름을 포함하도록 초기화되었으므로 기본 포털 이름은 기본적으로 커서 변수의 이름과 동일합니다. 이는 서로 다른 기능에서 비슷한 이름의 커서 간에 충돌이 발생할 위험이 너무 크기 때문에 변경되었습니다.

다음 예는 호출자가 커서 이름을 제공할 수 있는 한 가지 방법을 보여줍니다:

CREATE TABLE 테스트(열 텍스트);
테스트 값에 삽입('123');

CREATE FUNCTION reffunc(refcursor)는 refcursor AS '를 반환합니다.
시작
    테스트에서 열 선택을 위해 $1을 엽니다.
    $1를 반환합니다.
끝;
' 언어 plpgsql;

시작;
SELECT reffunc('펑커서');
funccursor에서 모두 가져오기;
커밋;

다음 예에서는 자동 커서 이름 생성을 사용합니다:

CREATE FUNCTION reffunc2()는 refcursor AS '를 반환합니다.
선언
    참조 참조자;
시작
    SELECT col FROM 테스트에 대한 OPEN 참조;
    반환 참조;
끝;
' 언어 plpgsql;

-- 커서를 사용하려면 트랜잭션에 있어야 합니다.
시작하다;
SELECT reffunc2();

      reffunc2
-------
 <이름 없는 커서 1
(1줄)

"<이름 없는 커서 1"에서 모두 가져오기;
커밋;

다음 예는 단일 함수에서 여러 커서를 반환하는 한 가지 방법을 보여줍니다.

함수 생성 myfunc(refcursor, refcursor)는 SETOF refcursor를 $$로 반환합니다.
시작
    SELECT * FROM table_1에 대해 $1 열기;
    다음 $1를 반환합니다.
    SELECT * FROM table_2를 위해 $2 열기;
    다음 $2를 반환합니다.
끝;
$$ 언어 plpgsql;

-- 커서를 사용하려면 트랜잭션에 있어야 합니다.
시작하다;

SELECT * FROM myfunc('a', 'b');

a에서 모두 가져오기;
b에서 모두 가져오기;
커밋;

43.7.4. 커서 결과 반복#

다음의 변형이 있습니다.for34912_35000

[ <<라벨 ]
에 대한recordvarINbound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ] 루프문장END 루프 [ 라벨 ];

커서 변수는 선언될 때 일부 쿼리에 바인딩되어 있어야 합니다.할 수 없습니다이미 열려있습니다.for문은 자동으로 커서를 열고 루프가 종료되면 커서를 다시 닫습니다. 실제 인수 값 표현식 목록은 커서가 인수를 사용하도록 선언된 경우에만 나타나야 합니다. 이 값은 쿼리에서와 동일한 방식으로 대체됩니다.열기(참조섹션 43.7.2.3).

변수recordvar자동으로 유형으로 정의됩니다.기록그리고 루프 내부에만 존재합니다(변수 이름의 기존 정의는 루프 내에서 무시됩니다). 커서에 의해 반환된 각 행은 이 레코드 변수에 연속적으로 할당되고 루프 본문이 실행됩니다.

수정사항 제출

문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.