在定义游标时不指定for update 或 for read only,ASE会检查以了解游标是否可更新;
如果游标查询语句中包含order by子句,则ASE会将游标定义为只读;其它情况下定义为可更新游标;
如果不涉及更新或删除表数据的话,建议在游标定义中加上for read only选项,这样ASE将游标定义为只读;
表customer在c_custkey列上建有唯一索引,查询表的前10行内容(所有字段拼接成一个字符串),
如果定义游标为for read only:
declare cur_hash cursor for select top 10 convert(varchar,c_custkey)+coalesce( nullif(isnull(c_name,''), '') , ' ')+coalesce( nullif(isnull(c_address,''),'') , ' ')+convert(varchar,c_nationkey)+coalesce( nullif(isnull(c_phone,''),'') , ' ')+convert(varchar,c_acctbal)+coalesce( nullif(isnull(c_mktsegment,''),'') , ' ')+coalesce( nullif(isnull(c_comment,''),'' ) , ' ') from customer for read only
则使用表扫描返回表的前10行数据;
如果定义游标为for update或者不指定for read only/for update:
则ASE会使用c_custkey列上的唯一索引扫描表数据,然后返回按照c_custkey键顺序的前10行数据;
对于该查询语句:select top 10 ... from customer,即使不指定for update,ASE也会将游标定义为可更新;
如果没有指定 for update 子句, ASE将选择任何唯一索引;如果指定表列没有唯一索引的情况下,它也可以使用其它索引或表扫描。
但如果指定了 for update 子句, ASE必须使用为一个或多个列定义的唯一索引扫描基表。如果不存在,则返回一个错误。
可以通过抽象计划来查看游标扫描表数据的时候是否使用了唯一索引:
查看在存储过程外声明的游标信息:
sp_cursorinfo null, cursor_name
查看在存储过程内声明的游标信息:
在存储过程内加入: exec sp_cursorinfo
存储过程sp_cursorinfo除了显示游标的状态信息外,还显示游标查询语句的抽象计划信息。
游标的状态不同输出也会不同,一般会输出:
1、游标定义、编译、扫描数据所使用的隔离级别;
2、游标是否可滚动;
3、游标当前位置;
4、游标已经读取/更新/删除的行数;
5、游标在事务提交或回滚后是否继续保持打开状态;
6、每次提取的行数;
7、游标是只读还是可更新的;
8、游标所消耗的内存数量;
9、游标返回的结果集的列数;
10、游标结果集的列信息(列类型、列宽度、是否可更新);
关于选项:set close on endtran
如果提交或回退游标的当前事务,默认情况下游标是保持打开状态;输出:The cursor will remain open when a transaction is committed or rolled back.
如果设置set close on endtran on则提交或回退游标的当前事务时游标会关闭;输出:The cursor will be closed when a transaction is committed or rolled back.