Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 参考 » 使用 SQL » SQL 语句 » SQL 语句 (E-O)

 

FETCH 语句 [ESQL] [SP]

此语句用于重新定位游标,然后从游标中获取数据。

语法
FETCH cursor-position cursor-name
[ INTO { hostvar-list | variable-list } | USING DESCRIPTOR sqlda-name ]
[ PURGE ]
[ BLOCK n ]
[ FOR UPDATE ]
[ ARRAY fetch-count ]
INTO variable-list [ FOR UPDATE ]
cursor-position :
    NEXT | PRIOR | FIRST | LAST
| { ABSOLUTE | RELATIVE } row-count
row-count : number or hostvar
cursor-name : identifier or hostvar
hostvar-list : may contain indicator variables
variable-list :  stored procedure variables
sqlda-name :  identifier
fetch-count :  integer or hostvar
参数
  • INTO 子句   INTO 子句是可选的。如果未指定该子句,则 FETCH 语句仅定位游标。hostvar-list 仅供嵌入式 SQL 使用。

  • cursor position   一个可选定位参数,它允许在读取行之前移动游标。如果读取操作中包括定位参数,且位置在允许的游标位置外,则会发出 SQLE_NOTFOUND 警告,并且由 SQLCOUNT 字段指示与有效位置之间的偏移量。

    OPEN 语句最初将游标定位在第一行的前面。

  • NEXT 子句   NEXT 是缺省定位参数,它使游标在读取行之前向前移动一行。

  • PRIOR 子句   使游标在读取前向后移动一行。

  • RELATIVE 子句   RELATIVE 定位用于在读取前将游标沿任一方向移动指定的行数。正数表示向前移动,负数表示向后移动。因此,NEXT 与 RELATIVE 1 等效,PRIOR 与 RELATIVE -1 等效。RELATIVE 0 检索的行与此游标的上一读取语句检索的行相同。

  • ABSOLUTE 子句   ABSOLUTE 定位参数用于转到具体行。0 表示第一行前面的位置(请参见在过程和触发器中使用游标)。

    1 表示第一行,依此类推。负数用于指定游标末尾的绝对位置。-1 表示游标的最后一行。

  • FIRST 子句   ABSOLUTE 1 的缩写形式。

  • LAST 子句   ABSOLUTE -1 的缩写形式。

    游标定位问题

    插入 DYNAMIC SCROLL 游标并对其进行某些更新会导致与游标定位有关的问题。除非 SELECT 语句中有 ORDER BY 子句,否则数据库服务器不将插入的行放在游标内可预知的位置。在有些情况下,插入的行要等到关闭并再次打开游标后才会出现。

    如果必须创建临时表才能打开游标,就会出现这种情况。有关说明,请参见在查询处理中使用工作表(使用 All-rows 优化目标)

    UPDATE 语句可能导致行在游标中移动。如果游标中具有使用现有索引的 ORDER BY 子句(未创建临时表),则会发生这种情况。

  • BLOCK 子句   客户端应用程序一次可读取多行。这类读取称为块读取、预读或多行读取。第一个读取会使数据库服务器发回若干行。客户端将这些行放入缓冲区,后续读取从这些缓冲区中检索,而不对数据库服务器发出新的请求。

    BLOCK 子句仅在嵌入式 SQL 中使用。它提示客户端和服务器:应用程序可读取多少行。特殊值 0 表示将请求发送到数据库服务器,并且只返回一行(没有行块)。BLOCK 子句会减少对 BLOCK 值的下一次预读中包含的行数。要增加预读的行数,可使用 PrefetchRows 连接参数。

    如果没有指定 BLOCK 子句,则使用执行 OPEN 时指定的值。请参见OPEN 语句 [ESQL] [SP]

    FETCH RELATIVE 0 总是重新读取行。

    如果禁用游标的预读,则会忽略 BLOCK 子句,且每次读取一行。如果还指定了 ARRAY,则读取 ARRAY 指定的行数。

  • PURGE 子句   PURGE 子句仅供嵌入式 SQL 使用。它使客户端刷新其所有行的缓冲区,然后向数据库服务器发送读取请求。请注意,此读取请求可能返回行块。

  • FOR UPDATE 子句   FOR UPDATE 子句指示读取的行随后将由 UPDATE WHERE CURRENT OF CURSOR 语句更新。使用此子句会使数据库服务器在行上加一个意图锁。该锁会一直保持到当前事务结束时为止。请参见锁定的工作方式SELECT 语句的 FOR UPDATE 子句。

  • ARRAY 子句   ARRAY 子句仅供嵌入式 SQL 使用。它允许所谓的宽读取(即同时检索多行)并会提高性能。

    要在嵌入式 SQL 中使用宽读取,请将 fetch 语句包括在代码中,如下所示:

    EXEC SQL FETCH ... ARRAY nnn

    其中 ARRAY nnn 是 FETCH 语句的最后一项。读取计数 nnn 可以是一个主机变量。SQLDA 必须包含 nnn *(每行的列数)个变量。第一行放在 SQLDA 变量 0 和(每行的列数)-1 之间,依此类推。

    有关使用宽读取的详细示例,请参见一次读取多个行

注释

FETCH 语句从指定的游标中检索一行。游标在此前必须已打开。

嵌入式 SQL 使用   在 C 源代码中,DECLARE CURSOR 语句必须出现在 FETCH 语句的前面,而 OPEN 语句必须在 FETCH 语句之前执行。如果主机变量用于游标名,则实际上是 DECLARE 语句生成代码,而且 DECLARE 语句必须在 FETCH 语句之前执行。

服务器在 SQLCOUNT 中返回读取的记录数,并且在没有错误或警告的情况下,返回的 SQLCOUNT 总是大于零。

如果在读取时返回 SQLSTATE_NOTFOUND 警告,则 SQLCA (SQLCOUNT) 的 sqlerrd[2] 字段中包含的值为尝试读取超出允许的游标位置的行数。如果未找到行但位置有效,则值为 0;例如,当定位到游标的最后一行上时执行 FETCH RELATIVE 1。如果所尝试的读取超出了游标的末尾,则为正值;如果所尝试的读取位于游标开头的前面,则为负值。如果所尝试的读取超出了游标的末尾,则游标定位到最后一行,如果所尝试读取位于游标开头的前面,则游标定位到第一行。

成功执行了读取语句后,SQLCA (SQLIOCOUNT) 的 sqlerrd[1] 字段递增,增量为执行读取所需的输入/输出操作数。此字段实际上在每个数据库语句执行时都递增。

单行读取   SELECT 语句结果中的一行被放入变量表的变量中。选择列表与主机变量列表之间是一对一的对应关系。

多行读取   SELECT 语句结果中的一行或多行放在 variable-list 的变量中或 sqlda-name 描述的程序数据区中。在上述任一种情况下,select-listhostvar-listsqlda-name 描述符数组之间都是一对一的对应关系。

权限

游标必须是打开的,并且用户必须对游标声明所引用的表具有 SELECT 权限。

副作用

无。

另请参见
标准和兼容性
  • SQL/2003   核心特性。在过程中使用的是持久存储模块特性。

示例

以下是嵌入式 SQL 的示例:

EXEC SQL DECLARE cur_employee CURSOR FOR
SELECT EmployeeID, Surname FROM Employees;
EXEC SQL OPEN cur_employee;
EXEC SQL FETCH cur_employee
INTO :emp_number, :emp_name:indicator;

以下是过程示例:

BEGIN
   DECLARE cur_employee CURSOR FOR
      SELECT Surname
      FROM Employees;
   DECLARE name CHAR(40);
   OPEN cur_employee;
   lp: LOOP
      FETCH NEXT cur_employee into name;
      IF SQLCODE <> 0 THEN LEAVE lp END IF;
       ...
   END LOOP;
   CLOSE cur_employee;
END