
# FETCH
#### 功能描述
FETCH通过已创建的游标来检索数据。
每个游标都有一个供FETCH使用的关联位置。游标的关联位置可以在查询结果的第一行之前，或者在结果中的任意行，或者在结果的最后一行之后：
- 游标刚创建完之后，关联位置在第一行之前的。
- 在抓取了一些移动行之后，关联位置在检索到的最后一行上。
- 如果FETCH抓取完了所有可用行，它就停在最后一行后面，或者在反向抓取的情况下是停在第一行前面。
- FETCH ALL或FETCH BACKWARD ALL将总是把游标的关联位置放在最后一行或者在第一行前面。
 
#### 注意事项
- 如果游标定义了NO SCROLL，则不允许使用例如FETCH BACKWARD之类的反向抓取。
- NEXT，PRIOR，FIRST，LAST，ABSOLUTE，RELATIVE形式在恰当地移动游标之后抓取一条记录。如果后面没有数据行，就返回一个空的结果，此时游标就会停在查询结果的最后一行之后（向后查询时）或者第一行之前（向前查询时）。
- FORWARD和BACKWARD形式在向前或者向后移动的过程中抓取指定的行数，然后把游标定位在最后返回的行上；或者是，如果count大于可用的行数，则在所有行之后（向后查询时）或者之前（向前查询时）。
- RELATIVE 0，FORWARD 0，BACKWARD 0都要求在不移动游标的前提下抓取当前行，也就是重新抓取最近刚抓取过的行。除非游标定位在第一行之前或者最后一行之后，这个动作都应该成功，而在那两种情况下，不返回任何行。
- 当FETCH的游标上涉及列存表时，不支持BACKWARD、PRIOR、FIRST等涉及反向获取操作。
 
#### 语法格式
```
FETCH [ direction { FROM | IN } ] cursor_name;
```
其中direction子句为可选参数。
```
NEXT
   | PRIOR
   | FIRST
   | LAST
   | ABSOLUTE count
   | RELATIVE count
   | count
   | ALL
   | FORWARD
   | FORWARD count
   | FORWARD ALL
   | BACKWARD
   | BACKWARD count
   | BACKWARD ALL
```
 #### 参数说明
表1FETCH参数说明 
| 参数                         | 描述                  | 取值范围                                                       |
|:---|:---|:---|
| direction_clause           | 定义抓取数据的方向。          | 参见[表2]。 |
| { FROM \| IN } cursor_name | 使用关键字FROM或IN指定游标名称。 | 已创建的游标的名称。                                                 |
   
 表2direction_clause取值范围 
| 取值范围                                                         | 描述                                                                                                           | 备注                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|:---|:---|:---|
| NEXT（缺省值）                                                    | 从当前关联位置开始，抓取下一行。                                                                                             | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| PRIOR                                                        | 从当前关联位置开始，抓取上一行。                                                                                             | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| FIRST                                                        | 抓取查询的第一行（和ABSOLUTE 1相同）。                                                                                     | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| LAST                                                         | 抓取查询的最后一行（和ABSOLUTE -1相同）。                                                                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ABSOLUTE count                                               | 抓取查询中第count行。 ABSOLUTE抓取不会比用相对位移移动到需要的数据行更快，因为下层的实现必须遍历所有中间的行。 | count取值范围：有符号的整数 - count为正数，就从查询结果的第一行开始，抓取第count行。当count小于当前游标位置时，涉及到rewind操作，暂不支持。  - count为负数或0，涉及到反向扫描操作，暂不支持。                                                                                               |
| RELATIVE count                                               | 从当前关联位置开始，抓取随后或前面的第count行。                               | count取值范围：有符号的整数 - count为正数就抓取当前关联位置之后的第count行。  - count为负数，涉及到反向扫描操作，暂不支持。  - 如果有数据的话，RELATIVE 0重新抓取当前行。   |
| count  | 抓取随后的count行（和FORWARD count一样）。                                                                               | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ALL                                                          | 从当前关联位置开始，抓取所有剩余的行（和FORWARD ALL一样）。                                                                          | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| FORWARD                                                      | 抓取下一行（和NEXT一样）。                                                                                              | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| FORWARD count                                                | 与RELATIVE count的效果相同，从当前关联位置开始，抓取随后或前面的第count行。                                                              | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| FORWARD ALL                                                  | 从当前关联位置开始，抓取所有剩余行。                                                                                           | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| BACKWARD                                                     | 从当前关联位置开始，抓取前面一行（和PRIOR一样）。                                                                                  | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| BACKWARD count                                               | 从当前关联位置开始，抓取前面的count行（向后扫描）。                                                                                 | count取值范围：有符号的整数 - count为正数就抓取当前关联位置之前的第count行。  - count为负数就抓取当前关联位置之后的第abs（count）行。  - 如果有数据的话，BACKWARD 0重新抓取当前行。   |
| BACKWARD ALL                                                 | 从当前关联位置开始，抓取所有前面的行（向后扫描） 。                                                                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   
#### 示例
示例一：SELECT语句，用一个游标读取一个表。
准备表数据。
```
DROP TABLE IF EXISTS customer_address;
CREATE TABLE customer_address 
(ca_address_sk INT, 
ca_address_id VARCHAR(16), 
ca_street_number VARCHAR(10), 
ca_street_name VARCHAR(60), 
ca_street_type VARCHAR(15), 
ca_suite_number VARCHAR(10));
INSERT INTO customer_address VALUES 
(1, 'ID1', '100', 'Main', 'St', 'A1'), 
(2, 'ID2', '200', 'Oak', 'Ave', 'B2'),
(3, 'ID3', '300', 'Pine', 'Blvd', 'C3');
```
建立一个名为cursor1的游标。
```
START TRANSACTION;
CURSOR cursor1 FOR SELECT * FROM customer_address ORDER BY 1;
```
抓取头3行到游标cursor1里。
```
FETCH FORWARD 3 FROM cursor1;
```
![](https://support.huaweicloud.com/sqlreference-dws/figure/zh-cn_image_0000002630493616.png "点击放大")
示例二：VALUES子句，用一个游标读取VALUES子句中的内容。
建立一个名为cursor2的游标。
```
CURSOR cursor2 FOR VALUES(1,2),(0,3) ORDER BY 1;
```
抓取头2行到游标cursor2里。
```
FETCH FORWARD 2 FROM cursor2;
```
![](https://support.huaweicloud.com/sqlreference-dws/figure/zh-cn_image_0000002660733077.png "点击放大")
#### 相关链接
[CLOSE](https://support.huaweicloud.com/sqlreference-dws/dws_06_0152.html)，[MOVE](https://support.huaweicloud.com/sqlreference-dws/dws_06_0217.html)
