FETCH
FETCH
커서(cursor)를 사용해 쿼리 결과에서 행을 가져오는 명령이에요. 커서는 결과 집합 안에서 위치를 갖고 있는데, FETCH는 그 위치를 따라 이동하며 앞뒤로 행을 읽어 와요. PL/pgSQL 함수 안에서는 규칙이 다르므로, 함수 내부에서 커서를 쓸 때는 관련 절을 참고해야 해요.
출처: PostgreSQL 문서
본문
개요 (Synopsis)
FETCH [ direction ] [ FROM | IN ] cursor_name
where direction can be one of:
NEXT
PRIOR
FIRST
LAST
ABSOLUTE count
RELATIVE count
count
ALL
FORWARD
FORWARD count
FORWARD ALL
BACKWARD
BACKWARD count
BACKWARD ALL
설명 (Description)
FETCH는 이전에 만든 커서를 사용해 행을 가져와요.
커서는 연관된 위치(position)를 갖고 있고, FETCH가 그 위치를 사용해요. 커서 위치는 쿼리 결과의 첫 행 앞, 결과의 어떤 특정 행 위, 또는 결과의 마지막 행 뒤일 수 있어요. 커서는 생성될 때 첫 행 앞에 위치해요. 몇 개의 행을 가져온 뒤에는 커서가 가장 최근에 가져온 행에 위치해요. FETCH가 사용 가능한 행의 끝을 지나가면 커서는 마지막 행 뒤에 위치하며, 뒤로 가져오는 경우에는 첫 행 앞에 위치해요. FETCH ALL이나 FETCH BACKWARD ALL은 항상 커서를 마지막 행 뒤 또는 첫 행 앞에 위치시켜요.
NEXT, PRIOR, FIRST, LAST, ABSOLUTE, RELATIVE 형태는 커서를 적절히 이동한 뒤 단일 행을 가져와요. 그런 행이 없으면 빈 결과를 반환하고, 커서는 상황에 맞게 첫 행 앞이나 마지막 행 뒤에 위치해요.
FORWARD와 BACKWARD를 사용하는 형태는 앞 또는 뒤 방향으로 이동하며 지정된 개수의 행을 가져오고, 커서는 마지막으로 반환된 행에 위치해요(count가 사용 가능한 행 수를 초과하면 모든 행의 뒤 또는 앞에 위치해요).
RELATIVE 0, FORWARD 0, BACKWARD 0은 모두 커서를 이동시키지 않고 현재 행을 가져오는, 즉 가장 최근에 가져온 행을 다시 가져오는 것을 요청해요. 커서가 첫 행 앞이나 마지막 행 뒤에 위치해 있지 않다면 성공해요. 그렇게 위치해 있다면 반환되는 행이 없어요.
NOTE:
이 페이지는 SQL 명령 수준에서의 커서 사용법을 설명해요. PL/pgSQL 함수 안에서 커서를 사용하려 한다면 규칙이 달라요 — 41.7.3절을 참고하세요.
파라미터 (Parameters)
*direction* — 가져올 방향과 행 수를 정의해요. 다음 중 하나일 수 있어요.
NEXT— 다음 행을 가져와요. direction을 생략하면 이것이 기본값이에요.PRIOR— 이전 행을 가져와요.FIRST— 쿼리의 첫 행을 가져와요(ABSOLUTE 1과 같아요).LAST— 쿼리의 마지막 행을 가져와요(ABSOLUTE -1과 같아요).ABSOLUTE count— 쿼리의 count 번째 행을, count가 음수라면 끝에서부터abs(count)번째 행을 가져와요. count가 범위를 벗어나면 첫 행 앞이나 마지막 행 뒤에 위치해요. 특히ABSOLUTE 0은 첫 행 앞에 위치시켜요.RELATIVE count— count 번째 다음 행을, count가 음수라면abs(count)번째 이전 행을 가져와요.RELATIVE 0은 있으면 현재 행을 다시 가져와요.*count*— 다음 count 개 행을 가져와요(FORWARD count와 같아요).ALL— 남은 모든 행을 가져와요(FORWARD ALL과 같아요).FORWARD— 다음 행을 가져와요(NEXT와 같아요).FORWARD count— 다음 count 개 행을 가져와요.FORWARD 0은 현재 행을 다시 가져와요.FORWARD ALL— 남은 모든 행을 가져와요.BACKWARD— 이전 행을 가져와요(PRIOR와 같아요).BACKWARD count— 이전 count 개 행을 가져와요(뒤로 스캔해요).BACKWARD 0은 현재 행을 다시 가져와요.BACKWARD ALL— 이전의 모든 행을 가져와요(뒤로 스캔해요).
*count* — 부호가 붙을 수 있는 정수 상수로, 가져올 위치나 행 수를 결정해요. FORWARD와 BACKWARD의 경우 음수 count를 지정하면 FORWARD와 BACKWARD의 의미가 뒤바뀌는 것과 같아요.
*cursor_name* — 열려 있는 커서의 이름이에요.
출력 (Outputs)
성공적으로 완료되면 FETCH 명령은 다음 형태의 명령 태그를 반환해요.
FETCH count
count는 가져온 행 수예요(아마 0일 수 있어요). psql에서는 명령 태그가 실제로 표시되지 않는데, psql이 가져온 행을 대신 표시하기 때문이라는 점을 참고하세요.
참고 (Notes)
FETCH NEXT나 양수 개수의 FETCH FORWARD 외의 FETCH 변형을 사용하려면 커서를 SCROLL 옵션으로 선언해야 해요. 단순한 쿼리의 경우 PostgreSQL은 SCROLL로 선언되지 않은 커서에서도 뒤로 가져오는 것을 허용하지만, 이 동작에 의존하지 않는 것이 좋아요. 커서가 NO SCROLL로 선언되었다면 뒤로 가져오는 것은 허용되지 않아요.
ABSOLUTE 가져오기는 원하는 행으로 상대 이동(relative move)으로 이동하는 것보다 빠르지 않아요. 기본 구현이 어쨌든 중간의 모든 행을 거쳐야 하기 때문이에요. 음수 절대 가져오기는 더 나빠요. 쿼리를 마지막 행을 찾기 위해 끝까지 읽고, 거기서 뒤로 거슬러 올라가야 하기 때문이죠. 다만 쿼리의 시작 부분으로 되감는 것(FETCH ABSOLUTE 0처럼)은 빠르답니다.
DECLARE는 커서를 정의하는 데 사용해요. 데이터를 검색하지 않고 커서 위치만 변경하려면 MOVE를 사용하세요.
예제 (Examples)
다음 예제는 커서를 사용해 테이블을 순회해요.
BEGIN WORK;
-- Set up a cursor:
DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;
-- Fetch the first 5 rows in the cursor liahona:
FETCH FORWARD 5 FROM liahona;
code | title | did | date_prod | kind | len
-------+-------------------------+-----+------------+----------+-------
BL101 | The Third Man | 101 | 1949-12-23 | Drama | 01:44
BL102 | The African Queen | 101 | 1951-08-11 | Romantic | 01:43
JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
P_302 | Becket | 103 | 1964-02-03 | Drama | 02:28
-- Fetch the previous row:
FETCH PRIOR FROM liahona;
code | title | did | date_prod | kind | len
-------+---------+-----+------------+--------+-------
P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
-- Close the cursor and end the transaction:
CLOSE liahona;
COMMIT WORK;
호환성 (Compatibility)
SQL 표준은 FETCH를 임베디드 SQL에서만 사용하도록 정의해요. 여기서 설명하는 FETCH 변형은 데이터를 호스트 변수에 넣는 대신 SELECT 결과처럼 반환해요. 이 점을 제외하면 FETCH는 SQL 표준과 완전히 위로 호환(upward-compatible)돼요.
FORWARD와 BACKWARD를 포함한 FETCH 형태와, FORWARD가 암시되는 FETCH count 및 FETCH ALL 형태는 PostgreSQL 확장이에요.
SQL 표준은 커서 이름 앞에 FROM만 허용해요. IN을 사용하거나 아예 생략하는 옵션은 확장이에요.
더 알아보기 (Learn more)
커서를 정의하는 방법은 DECLARE 문서를, 데이터를 검색하지 않고 커서 위치만 옮기는 방법은 MOVE 문서를, 커서를 닫는 방법은 CLOSE 문서를 함께 보면 좋아요.