FETCH 语句
FETCH语句将光标定位在其结果表的一行上。 它可以返回零、一行或多行,如果有目标说明,则将行的值赋给变量。
调用 FETCH
此语句只能嵌入在应用程序中。 这是一个无法动态准备的可执行语句。 REXX、 Fortran 或SQL程序应用不支持多行获取 1。 REXX不支持带有WITH CONTINUE子句的FETCH语句。
授权 FETCH
请参阅 DECLARE CURSOR语句 ,了解使用游标所需的授权。
对于赋值给全局变量或数组元素的全局变量,权限集必须至少包含以下内容之一:

- 可变WRITE权限
- 可变的所有权
- DATAACCESS 权限
- SYSADM 权限

对于过渡变量的赋值,权限集必须至少包含以下内容之一:

- 定义了包含赋值语句的触发器的表或视图的UPDATE权限
- 更新列中与待赋值的过渡变量相对应的列的权限
- 包含赋值语句的触发器所在的表格或视图的所有权
- DBADM 数据库权限,其中包含定义了包含赋值语句的触发器的表
- DATAACCESS 权限
- SYSADM 权限

权限集: 如果该语句嵌入在应用程序中,则权限集就是包的所有者所拥有的权限。 如果语句是动态准备的,则权限集由生效的DYNAMICRULES行为(运行、绑定、定义或调用)确定,并在 DYNAMICRULES行为和授权检查中汇总。 如需了解这些行为的更多信息,包括确定这些行为的DYNAMICRULES绑定选项值的列表,请参阅授权ID和动态SQL。
语法 FETCH
- 1 默认值取决于光标的灵敏度。 如果在DECLARE CURSOR中指定了INSENSITIVE,则默认值为INSENSITIVE;如果在DECLARE CURSOR中指定了SENSITIVE,则默认值为SENSITIVE。
- 2 如果指定了“不敏感”或“敏感”,则必须指定单行获取或多行获取。
- 3 如果指定了 WITH CONTINUE,则必须指定单行取值。
- 4 如果指定了多行获取 ,则还必须指定行集定位的获取方向。
取向
- 1 如果指定了“之前”或“之后”,则不能指定“敏感”、“不敏感 ”、“单行获取 ”或 “多行获取 ”。
- 2 仅当未指定多行取值时,才能指定行定位取值方向。
- 3 如果指定了多行获取 ,则必须同时指定行集定位的获取方向。
取回类型
- 1 对于单行取值,可以指定主机变量数组来代替主机变量。 描述符可以描述宿主变量数组。 无论哪种情况,数据仅返回主机变量数组中的第一个条目。
- 2 只能在SQL PL上下文中指定数组元素。
- 3 仅可在 SQL PL 上下文中指定数组全局变量。
- 4 如果取货方向为行式取货 ,或者未指定取货方向,则不得指定本条款。
- 5 本条款为可选条款。 如果未指定此子句,并且行集大小尚未确定,或者定位FETCH语句是为此游标发出的最后一类FETCH语句,则行集大小默认为1。 如果为该游标发出的最后一个 FETCH 语句是定位行集 FETCH 语句,且未指定此子句,则行集大小与上一个定位行集 FETCH 语句相同。
描述 FETCH
- INSENSITIVE
- 按原样返回结果表中的行。 如果该行之前已经通过FETCH SENSITIVE获取,则它反映FETCH SENSITIVE语句发出之前光标之外所做的更改。 如果定位更新或删除操作使用了相同的游标,则定位更新和删除操作会通过“FETCH INSENSITIVE”进行反映。
INSENSITIVE只能用于声明为INSENSITIVE或SENSITIVE STATIC的游标(或者如果游标声明为ASENSITIVE,则 Db2 默认为INSENSITIVE)。 否则,如果光标被声明为 SENSITIVE DYNAMIC(或者如果光标被声明为 ASENSITIVE,而 Db2 默认为 SENSITIVE DYNAMIC),则会发生错误,FETCH 语句将不起作用。 对于INSENSITIVE光标,指定INSENSITIVE是可选的,因为它是默认设置。
- SENSITIVE
- 从游标SELECT语句的基表中的相应行更新结果表中的已获取行,并返回当前值。 因此,它反映了光标之外的变化。 敏感光标只能指定敏感光标。 否则,如果光标不灵敏,就会发生错误,FETCH语句将不起作用。 对于敏感光标,指定敏感是可选的,因为它是默认设置。
当光标被定义为“静态敏感”且请求“FETCH SENSITIVE”时,将执行以下步骤:
- Db2 检索与即将获取的结果表中的行相对应的数据库行。
- 如果相应行已被删除,结果表中会出现一个“删除孔”,系统会发出警告,光标会重新定位到“孔”上,且不会提取任何数据。(当数据库中的相应行被删除时,Db2 会在结果表中将该行标记为“删除孔”。)
- 如果对应行未被删除,则重新评估基础 SELECT 语句的谓词。 如果该行不再满足谓词,结果表中就会出现“更新漏洞”,系统会发出警告,光标会重新定位到“漏洞”处,并且不会提取任何数据。当数据库中对应行的更新导致该行不再符合结果表的条件时,Db2 会将结果表中的该行标记为“更新漏洞”
- 如果相应行不会导致结果表中删除或更新漏洞,则光标将重新定位到结果表的行上,并获取数据。
- 继续
- 指定 Db2 子系统应做好准备,允许后续FETCH CURRENT CONTINUE操作访问任何截断的LOB或XML结果列,前提是初始FETCH操作提供的输出变量不足以容纳整个LOB或XML列。 当指定 WITH CONTINUE 子句时, Db2 子系统会执行以下操作,这些操作可能与 FETCH 语句不包含 WITH CONTINUE 子句的情况有所不同:
- 如果返回XML或LOB列时发生截断, Db2 子系统将记住截断位置,不会丢弃剩余数据。
- 如果返回XML或LOB列时发生截断, Db2 子系统将返回保存LOB或XML列的所有数据所需的总体长度。 该值将位于LOB主机变量结构的四个字节中,或者位于SQLDA中该主机变量的SQLVAR条目中SQLDATALEN指针所指向的4字节区域中。 返回的结果取决于所使用的编程方法。 有关SQLDA内容的详细信息,请参阅 SQL描述符区(SQLDA )。
- 如果返回XML数据,结果列将在数据返回之前在数据库中完全实现。
如果指定了 CURRENT CONTINUE 子句,则假定 WITH CONTINUE 行为。
- AFTER
- 将光标定位在结果表最后一行的后面。 值不会分配给宿主变量。 对于INSENSITIVE或SENSITIVE STATIC有效灵敏度的游标,结果表的行数在SQLCA的 SQLERRD1 和 SQLERRD2 字段中返回。
- BEFORE
- 将光标定位在结果表第一行之前。 值不会分配给宿主变量。
- 排定位置
- 光标定位与行定位的获取方向(下一个、上一个、当前和相对)是相对于当前光标位置进行的。 在成功执行行定位FETCH语句后,光标将定位在单行数据上。 如果光标已启用行集,则定位操作将相对于当前行或当前行集的第一行执行,光标将定位在由单个行组成的行集上。
- 下一步
- 将光标定位在当前光标位置结果表的下一行或几行,如果指定了目标,则返回数据。 NEXT是唯一一行定位的取操作,可以明确指定给定义为“无滚动”的游标。 如果没有指定其他光标定位,则默认使用“下一步”。 如果指定的行出现空值,系统会发出警告,并且不会将该行的数据值分配给宿主变量。
表1 列出了不同光标位置的情况以及使用NEXT时的结果。
表 1. 当NEXT用于不同的光标位置时,结果如下 光标的当前状态 FETCH NEXT的结果 第一排之前 光标位于第一行1 ,如果需要,将返回数据。 最后一排或最后一排之后 出现警告,值未分配给宿主变量,光标位置不变。 在洞之前 对于敏感静态游标,删除孔或更新孔会出现警告,值不会分配给宿主变量,游标会定位在孔上。 未知 发生错误,值未分配给宿主变量,光标位置仍然未知。 注:- 当光标只能向前移动时(即当未明确或隐含指定“无滚动”时),此行不适用。
- PRIOR
- 将光标定位在当前光标位置之前的结果表行,如果指定了目标,则返回数据。 如果指定的行出现空值,系统会发出警告,并且不会将该行的数据值分配给宿主变量。
表2 列出了不同光标位置的情况以及使用PRIOR时的结果。
表 2. PRIOR在不同光标位置下的结果 光标的当前状态 FETCH PRIOR的结果 第一排之前或第一排 出现警告,值未分配给宿主变量,光标位置不变。 打了一个洞之后 对于敏感静态游标,删除孔或更新孔会出现警告,值不会分配给宿主变量,游标会定位在孔上。 最后一排之后 光标位于最后一行。 未知 发生错误,值未分配给宿主变量,光标位置仍然未知。 - FIRST
- 将光标置于结果表的第一行,如果指定了目标,则返回数据。 对于敏感的静态游标,如果结果表的第一行是一个洞,则会发出警告,提示删除洞或更新洞,并且不会将值分配给宿主变量。
- LAST
- 将光标放在结果表的最后一行,如果指定了目标,则返回数据。 SQLCA的 SQLERRD1 和 SQLERRD2 字段中返回结果表的行数,用于不敏感或敏感的静态游标。 对于敏感的静态光标,如果结果表的最后一行为空,则会发出警告,提示删除空值或更新空值,并且不会将值分配给宿主变量。
- CURRENT
- 光标位置不变,如果指定了目标,则返回数据。 如果光标位于多行行集上,则光标位置在行集的第一行。
表3 列出了CURRENT子句出现错误的情况。
表 3. 当前发生错误的情况 光标的当前状态 FETCH CURRENT的结果 第一排之前或最后一排之后 出现警告,值未分配给宿主变量,光标位置不变。 在一个洞里 对于敏感静态,删除孔或更新孔会出现警告,值未分配给宿主变量,光标位于孔上。 如果游标被定义为行集游标,隔离级别为UR或敏感动态可滚动游标,则返回的行可能与确定最近游标位置的FETCH不同。 当确定该行不再存在时,再次获取该行时可能会发生这种情况。 在这种情况下,获取操作将继续前进,以获取一行数据。
未知 发生错误,值未分配给宿主变量,光标位置仍然未知。 - CONTINUE
- 光标位置不变,如果指定了目标,则返回数据。 FETCH CURRENT CONTINUE语句用于检索在之前的FETCH或FETCH CURRENT CONTINUE语句中被截断的任何LOB或XML列结果值的剩余数据。 它将剩余数据分配给语句中引用的或描述符指向的主变量。 先前截断的结果值返回的数据从截断点开始。 当前子句的这种形式仅用于单行 FETCH WITH CONTINUE 或 FETCH CURRENT CONTINUE 语句返回一个或多个 LOB 或 XML 列的部分数据之后。 光标必须处于打开状态并位于某一行上。
FETCH CURRENT CONTINUE 必须传递 SELECT 列表中所有列的主变量条目,即使非 LOB 列或非 XML 列不会返回任何数据。
- 绝对值
- host-variable 或 integer-constant 被赋值给一个整数 k。 如果指定了宿主变量 ,则该变量必须为精确数值类型,且比例系数为零,且不得包含指示变量。 主机变量的可能数据类型为 DECIMAL(n,0) 或整数。 DECIMAL数据类型限制为DECIMAL(18,0)。 整数常量最多可有31位数字,具体取决于应用程序的语言。
如果 k=0 ,光标位于结果表第一行之前。 否则,如果 k>0 ,ABSOLUTE 将光标定位到结果表的 k 行 ,如果 k<0 ,则定位到距表底部的 k 行。 例如,“ABSOLUTE -1" ”与“LAST”相同。
如果指定位置在结果表的行内,且指定了目标,则返回数据。
如果指定了绝对位置,即结果表的第一行之前或最后一行之后,则会发出警告,值不会分配给宿主变量,光标会定位在第一行之前或最后一行之后。 如果结果光标位置在INSENSITIVE和SENSITIVE STATIC滚动光标的最后一行之后,则结果表的行数将返回到SQLCA的 SQLERRD1 和 SQLERRD2 字段中。 如果结果表的第 k 行为空,则会出现警告,并且不会将值分配给宿主变量。
FETCH ABSOLUTE 0 结果在第一行之前定位,并发出警告。 FETCH BEFORE 会导致在第一行之前定位,且不会发出警告。
表4 列出了部分同义规格。
表 4. 滚动条规格的同义词 ABSOLUTE 规范 备用 绝对0(但有警告) 之前(无预警) 绝对值 +1 FIRST 绝对 -1 LAST 绝对值 -m , 0<m≤n 绝对 n +1- m 绝对 n LAST 绝对值 - n FIRST 绝对值 x (带有警告) 之后(毫无预警) 绝对值 -x (带有警告) 之前(无预警) 注意: 假设:0<= m <= n < x 其中, n 是结果表中的行数。 - RELATIVE
- host-variable 或 integer-constant 被赋值给一个整数 k。 如果指定了宿主变量 ,则该变量必须为精确数值类型,且比例系数为零,且不得包含指示变量。 主机变量的可能数据类型为 DECIMAL(n,0) 或整数。 DECIMAL数据类型限制为DECIMAL(18,0)。
如果光标位于结果表的第一行之前或最后一行之后,则按以下方式确定光标位置:
- 如果 n 为0,光标位置不变,值不会分配给宿主变量,并出现警告
- 如果 n 为正数,且光标位于第一行之前,则光标位于从第n行开始的行集上
- 如果 n 为正数,且光标位于最后一行之后,则会发出警告
- 如果 n 为负数,且光标位于第一行之前,则会显示警告
- 如果 n 为负数,且光标位于最后一行之后,则光标位于从结果表末尾开始从第n行开始的行集上
整数常量最多可有31位数字,具体取决于应用程序的语言。
如果指定位置在结果表的行内,且指定了目标,则返回数据。
RELATIVE 将光标定位到结果表中当前行之后的 k 行 (如果 k>0 ),或者当前行之前的 ABS(k) 行 (如果 k<0 )。 例如,“RELATIVE -1" ”与“PRIOR”相同。 如果 k=0 ,光标的位置不变(即“RELATIVE 0”与“CURRENT”相同)。
如果指定了相对位置,导致定位在第一行之前或最后一行之后,则会发出警告,不会将值分配给宿主变量,光标会定位在第一行之前或最后一行之后。 如果结果光标位置在INSENSITIVE和SENSITIVE STATIC可滚动光标最后一行之后,则结果表的行数将返回到SQLCA的 SQLERRD1 和 SQLERRD2 字段中。 如果光标位于一个洞上,并且指定了相对0,或者目标行是一个洞,则会发出警告,并且不会将值分配给宿主变量。
如果游标被定义为行集游标,隔离级别为UR或敏感动态可滚动游标,则返回的行可能与确定最近游标位置的FETCH不同。 当确定该行不再存在时,再次获取该行时可能会发生这种情况。 在这种情况下,获取操作将继续向前,以获取行数据。
如果光标位置未知,且指定了相对0,则会发生错误。
表5 列出了部分同义规格。
表5。 Synonymous Scroll 规格 RELATIVE 规范 备用 亲戚 +1 下一步 亲戚 -1 PRIOR 相对值 0 CURRENT 相对 +r (带有警告) 之后(毫无预警) 相对 -r (带有警告) 之前(无预警) 注意: r 必须足够大,以便将光标定位在结果表的两端之外。
- 排定位置
光标定位与行集定位的获取方向(下一行集、前一行集、当前行集和从相对行集开始)是相对于当前光标位置进行的。 在成功执行行集定位的FETCH语句后,光标将定位在数据行集上。 行集中的行数可以显式或隐式确定。 多行获取子句中的FOR n ROWS 子句用于明确指定行集的大小。 定位是相对于当前行集的当前行或第一行进行的,光标位于行集的所有行上。
如果当前光标位置未定义为访问行集,则不得指定行集定位的获取方向。 NEXT ROWSET是唯一可为定义为“无滚动”的游标指定的行集定位取向。
如果行集中有一行出现空值,系统会发出警告,不将该行的数据值分配给宿主变量数组(即目标宿主变量数组中的对应位置不变),并且在该行的所有指示变量中返回 -3。 如果检测到漏洞,且至少有一个指示变量未提供,则会发生错误。
- 下一行
- 将光标定位在当前光标位置对应的结果表下一行,如果指定了目标,则返回数据。 逻辑上,通过获取当前行集之后的行集,并获取额外的行,直到在FOR n ROWS子句中隐式或显式指定的行数或到达结果表的最后一行,即可获得下一行集。
如果光标位于结果表的第一行之前,则光标位于第一行组上。
如果光标位于结果表的最后一行或最后一行之后,光标位置将保持不变,值不会分配给宿主变量数组,并出现警告。
如果行集中的一行反映了一个洞,则会发生以下操作:
- 返回警告。
- 数据值未分配给该行的宿主变量数组(即目标宿主变量数组中的相应位置未更改)。
- 为该行提供的所有指标变量均返回 -3。
如果检测到漏洞,且至少有一个指示变量未提供,则返回错误。
如果光标因先前错误而未定位,则不会为主变量数组分配值,并返回错误。 如果结果表的最后一行之后还有一行,则不会为该行以及行集中的任何后续请求行的主变量数组赋值,并返回警告。
NEXT ROWSET是唯一可明确指定为“无滚动”游标的定位取向。
- 以前的行集
- 将光标定位在当前位置结果表的上一个行集上,如果指定了目标,则返回数据。
逻辑上,通过获取当前行集之前的行集,并获取额外的行,直到在FOR n ROWS子句中隐式或显式指定的行数,或者到达结果表的最后一行,即可获得前一行集。
如果光标位于结果表最后一行之后,则光标位于最后一组行上。
如果光标位于结果表的第一行之前或第一行上,则光标位置不变,值不会分配给宿主变量数组,并出现警告。
如果一行位于结果表的第一行之前,则光标位于一个部分行集上,该部分行集仅包含从结果表第一行开始、位于光标当前位置之前的行,此时将返回一条警告。 对于行集中返回警告的行,不会为宿主变量数组分配值。
虽然逻辑上是从当前行集之前向后获取行集,但数据是从行集的第一行开始返回到应用程序的最后一行的。
如果行集中的一行反映了一个洞,则会发生以下操作:
- 返回警告。
- 数据值未分配给该行的宿主变量数组(即目标宿主变量数组中的相应位置未更改)。
- 为该行提供的所有指标变量均返回 -3。
如果检测到漏洞,且至少有一个指示变量未提供,则返回错误。
如果光标因先前错误而未定位,则不会为主变量数组分配值,并返回错误。
- 第一行
- 将光标置于结果表的第一行,如果指定了目标,则返回数据。
如果行集中的一行反映了一个洞,则会发生以下操作:
- 返回警告。
- 数据值未分配给该行的宿主变量数组(即目标宿主变量数组中的相应位置未更改)。
- 为该行提供的所有指标变量均返回 -3。
如果检测到漏洞,且至少有一个指示变量未提供,则返回错误。
如果结果表中的行数少于 FOR n ROWS 子句中隐式或显式指定的行数,则在结果表的最后一行之后,不会将值分配给宿主变量数组,并返回警告。
- 最后一行
- 将光标置于结果表的最后一行,如果指定了目标,则返回数据。 最后一组行集的逻辑获取方式是:获取结果表的最后一行,然后向前获取行,直到获取到所需行数或到达结果表的第一行。 虽然逻辑上是从结果表的底部向后获取行集,但数据是从行集的第一行开始返回到应用程序的,直到行集的末尾,也就是结果表的末尾。
如果行集中的一行反映了一个洞,则会发生以下操作:
- 返回警告。
- 数据值未分配给该行的宿主变量数组(即目标宿主变量数组中的相应位置未更改)。
- 为该行提供的所有指标变量均返回 -3。
如果检测到漏洞,且至少有一个指示变量未提供,则返回错误。
如果结果表中的行数少于在 FOR n ROWS 子句中隐式或显式指定的行数,则最后一个行集与第一个行集相同,在结果表的最后一行之后,值不会分配给宿主变量数组,并且会返回一条警告。
- 当前行
- 如果 FOR n ROWS 子句指定的行数与最近一次 FETCH 语句的 FOR n ROWS 子句中隐式或显式指定的行数不同,则游标将从当前行集的第一行开始,重新定位到指定的行数。 如果光标位于结果表的第一行之前或最后一行之后,则光标位置不变,值不会分配给宿主变量数组,并出现警告。 如果未指定 FOR n ROWS 子句 ,则当处理 FETCH CURRENT ROWSET 语句时,FETCH 语句可能会将光标定位在部分行集上。 在这种情况下, Db2 尝试将光标定位在当前行集的第一行开始的完整行集上。 否则,光标在当前行集中的位置保持不变。 如果指定了目标,则返回数据。
使用隔离级别UR或灵敏的动态可滚动光标时,返回的行可能与确定最近行集光标位置的FETCH不同。 当确定第一行不再存在时,在重新获取该行时可能会发生这种情况。 在这种情况下,获取操作将继续前进,以获取行集的第一行数据。 当当前行集中的其他行发生更改,导致它们不再存在或从光标的结果表中逻辑移动(或移出)时,也会出现这种情况。
如果光标因之前的错误而无法定位,则不会为主变量数组分配值,并发生错误。
如果当前行集包含的行数少于 FOR n ROWS 子句中隐式或显式指定的行数,则不会将值分配给最后一个行之后的主变量数组,并返回警告。
- 行集,从绝对或相对主机变量 或 整数常量开始
- 将光标定位在以绝对或相对规格指定的结果表行开始的行集上,如果指定了目标,则返回数据。
host-variable 或 integer-constant 被赋值给一个整数 k。 如果指定了宿主变量 ,则该变量必须为精确数值类型且比例系数为零,且不得包含指示变量。 主机变量的可能数据类型为DECIMAL( n,0 )或整数,其中DECIMAL数据类型限制为DECIMAL(18,0)。 如果指定了常量,则该值必须为整数。
如果结果表的一行位于结果表的最后一行之后或第一行之前,则不会为该行的宿主变量数组分配值,并返回警告。
- 绝对值
- 如果 k=0 ,则发生错误。 如果 k>0 ,则行集的第一行是第k行。 如果 k<0 ,则结果集从结果表底部开始位于ABS(k)行。 假设 ABS(k) 等于行集的行数,并且有足够的行返回完整的行集:
- FETCH ROWSET STARTING AT ABSOLUTE -k 与FETCH LAST ROWSET相同。
- FETCH ROWSET STARTING AT ABSOLUTE 1 与 FETCH FIRST ROWSET 相同。
- RELATIVE
- 如果 k=0 和 FOR n ROWS子句没有指定一个与最近为该游标隐式或显式指定的数字不同的数字,则游标的位置不会改变(即“RELATIVE ROWSET 0”与“CURRENT ROWSET”相同)。 如果 k=0 和 FOR n ROWS子句指定的行数与最近一次为该游标隐式或显式指定的行数不同,则游标将从当前行集的第一行开始,重新定位到指定的行数。
如果光标位于结果表的第一行之前或最后一行之后,则按以下方式确定光标位置:
- 如果 n 为 0,光标位置不变,值不会分配给宿主变量,并出现警告。 这与FETCH CURRENT ROWSET相同。
- 如果 n 为正数,且光标位于第一行之前,则光标位于从第n行开始的行集上。
- 如果 n 为正数,且光标位于最后一行之后,则会发出警告。
- 如果 n 为负数,且光标位于第一行之前,则会发出警告。
- 如果 n 为负数,且光标位于最后一行之后,则光标位于结果表底部从第n行开始的行集中。
- FETCH ROWSET STARTING AT RELATIVE -k 与FETCH PRIOR ROWSET相同。
- FETCH ROWSET STARTING AT RELATIVE k 与FETCH NEXT ROWSET相同。
- FETCH ROWSET STARTING AT RELATIVE 0 与 FETCH CURRENT ROWSET 相同。
当指定了相对 -n 的起始行,并且光标当前位置与结果表开头之间的行数不足以返回完整行集时:
- 返回警告。
- 宿主变量数组没有赋值。
- 光标位于第一行之前。
如果行集中的一行反映了一个洞,则会发生以下操作:
- 返回警告。
- 数据值未分配给该行的宿主变量数组(即目标宿主变量数组中的相应位置未更改)。
- 为该行提供的所有指标变量均返回 -3。
如果检测到漏洞,且至少有一个指示变量未提供,则返回错误。 如果行集的某一行未知,则不会为该行的宿主变量数组分配值,并返回错误。 如果结果表最后一行之后或第一行之前有一行行集,则不会为该行的主变量数组赋值,并返回警告。
- 光标名称
- 标识在获取操作中使用的光标。 游标名称必须标识已声明的游标 (如DECLARE CURSOR语句中的DECLARE CURSOR语句说明所述)或已分配的游标( 如ALLOCATE CURSOR语句所述)。 执行FETCH语句时,光标必须处于打开状态。
如果未指定单行获取或多行获取子句,则光标位置会按照指定方式调整,但不会向用户返回任何数据。
- 单行取
- 当指定单行取值时,可以指定敏感或非敏感,但有一个默认值。 默认值取决于光标的灵敏度。 如果光标的灵敏度为“不灵敏”,则默认值为“不灵敏”。 如果光标的有效灵敏度为“动态灵敏”或“静态灵敏”,则默认值为“灵敏”。 当指定FETCH BEFORE或FETCH AFTER选项时,不能指定单行获取或多行获取子句。 当未指定“提前取货”或“延迟取货”时,需要填写这些信息。 如果单个获取操作导致光标定位或保持在有目标规格的行上,则结果表的值将按单个获取子句的指定分配给宿主变量。
- INTO 目标变量或数组变量 [数组索引 ]
- FL 500 确定一个或多个目标,用于输出值的分配。 INTO子句中的目标数量必须与要分配的值数量相等。 结果行中的第一个值分配给列表中的第一个目标,第二个值分配给第二个目标,以此类推。 在INTO子句中,目标变量不能被指定多次。 根据 “任务和比较” 中描述的规则,按照列表中的顺序为每个目标分配任务。
如果目标数量少于结果列的值数量,则将值“W”分配给SQLCA的 SQLWARN3 字段。
如果任何赋值操作出错,则不会将值赋给目标,也不会再向指定目标赋值。 任何已分配的值将保持不变。
全局变量名
FL 500标识作为赋值目标的全球变量。 全局变量只能在SQL PL上下文中指定。 当全局变量被指定为赋值目标时,光标必须不可滚动。
- 主机变量名
- 标识作为赋值目标的主变量。 对于LOB输出值,目标可以是常规的主变量(如果足够大)、LOB定位变量或LOB文件引用变量。
- SQL参数名称
- 标识作为赋值目标的参数。
- SQL变量名
- 标识作为赋值目标的SQL变量。 SQL变量在使用前必须声明。
- 数组变量 [数组索引]
- 指定作为赋值目标的数组元素。
- 数组变量
- 指定和数组变量。
- [数组索引 ]
- 用于指定数组中哪个元素是赋值目标。
对于普通数组,数组索引表达式必须可转换为整数,且不能为空值。 索引值必须在1和数组定义的最大基数之间。
对于关联数组,数组索引表达式必须可转换为关联数组的索引数据类型,且不能为空值。
数组索引不能为:
- 引用当前日期、当前时间或当前时间戳特殊寄存器的表达式
- 非确定性函数
- 由外部动作定义的功能
- 用MODIFIES SQL DATA定义的函数
- 序列表达式
过渡变量名
标识转换表中要更新的列。 过渡变量名必须标识触发器主表中的列,可选地由标识新值的关联名限定。
- INTO DESCRIPTOR 描述符名称
- 标识包含主机输出变量有效描述的 SQLDA。 相关 SELECT 语句的结果值将作为输出主机变量返回给应用程序。
在处理FETCH语句之前,您必须在SQLDA中设置以下字段:
- SQLN 用于指示 SQLDA 中提供的 SQLVAR 出现的次数
REXX SQLDA 不包含此字段。
- SQLABC用于指示SQLDA中分配的存储字节数
- SQLD 用于指示处理语句时 SQLDA 中使用的变量数量
- SQLVAR的出现次数,表示变量的属性
SQLDA必须具有足够的存储空间来容纳所有SQLVAR的出现。 每个SQLVAR的出现描述了一个主机变量或缓冲区,结果表中的值将被分配到该主机变量或缓冲区中。 如果结果中出现LOB,则结果表的每一列都必须有额外的SQLVAR条目。 如果结果表中只包含基本类型和不同类型,则无需为每列添加多个SQLVAR条目。 然而,在描述和准备进入语句中,对于不同的类型以及LOB,需要额外的SQLVAR条目。 如需了解SQLDA的更多信息,包括SQLVAR的描述以及如何确定SQLVAR出现次数的说明,请参阅 SQL描述符区域(SQLDA )。
SQLD必须设置为大于或等于零且小于或等于SQLN的值。
请参阅 《在C或C++中识别SQLDA 》,了解如何在C中表示描述符名称。
- SQLN 用于指示 SQLDA 中提供的 SQLVAR 出现的次数
- 多行取回
- 从查询结果表中检索多行数据。 FETCH语句中的FOR n ROWS子句控制着FETCH语句一次返回的行数。 取值方向决定了光标的位置(例如,在单行、行集、结果表之前或之后)。 当返回错误、所有请求的行都已获取或数据条件结束时,获取操作将停止。
可通过可滚动或不可滚动光标获取多行数据。 用于定义、打开和关闭游标的操作与用于单行FETCH语句的操作相同,游标用于获取多行数据。
如果指定了“之前”或“之后”选项,则不能指定单行取值或多行取值。
- 对于宿主变量 或 整数常量行
- host-variable 或 integer-constant 被赋值给一个整数 k。 如果指定了宿主变量,则该变量必须为精确数值类型,且比例系数为零,且不得包含指示变量。 此外 ,k 必须在范围内, 0<k<=32767。
如果指定了行定位取向子句,则不得指定此子句。 对于没有定义行集访问权限的光标,也不得指定此条款。
如果指定了行集获取方向,但未指定此子句,则结果行集中的行数按以下方式确定:
- 如果此游标的最新FETCH语句是行集定位FETCH,则行集的行数由最近为此游标指定的行数(隐式或显式)隐式确定。
- 当此游标的最近FETCH语句为FETCH BEFORE或FETCH AFTER,且此游标之前的最近FETCH语句为行集定位FETCH时,行集的行数由最近为此游标指定的行数(隐式或显式)隐式确定。
- 否则,行集由单个行组成。
对于结果集游标,当返回行集时,调用方不会继承在定义行集的过程中为行集游标位置确定的行数。 在调用程序中的结果集的第一行集FETCH语句上使用 FOR n ROWS子句来确定游标的行数。 否则,行集由单个行组成。
光标位于由方向子句(例如NEXT ROWSET)指定的行或行集上,如果指定了目标,则获取这些行。 光标定位在要提取的第一行后,将提取接下来的 k-1 行。 从结果表中的光标位置向前提取数据,直到返回数据条件结束、提取了 k-1 行或返回分配错误。
光标位置取决于指定的获取方向:
- 对于行定位的获取方向,光标位于成功检索到的最后一行。
- 对于行定位的获取方向,光标位于所有已检索的行上。
每个单独取值的值被放置在数据区域中,这些数据区域在INTO或USING子句中进行了描述。 如果为行集定位的 FETCH 提供了目标规格,则必须将主机变量数组指定为目标规格,并且数组的维度必须为 1 或更大。 目标规格必须定义为行集定位FETCH的数组,即使隐式或显式指定的行数为1。 请参阅诊断信息,了解行集定位FETCH语句。
- INTO host-variable-array
- 为结果表的每一列指定一个主机变量数组,用于接收通过FETCH语句检索的数据。 如果宿主变量数组数量小于结果表的列数,则SQLCA的 SQLWARN3 字段将设置为“W”。 如果宿主变量数组大于结果表的列数,则不会发出警告。
每个宿主变量数组必须根据数组声明规则在应用程序中定义。 主机变量数组用于返回结果表一列的值。 要获取的行数必须小于或等于每个宿主变量数组的维度。
可以为主机变量数组指定可选的指示器数组。 如果任何SQLVAR的SQLTYPE表明结果表的列为空,则应予以说明。 此外,如果操作可能会导致空值,例如在应用程序中执行UPDATE操作会导致漏洞,则应指定指示数组。 否则,如果遇到空值,就会发生错误。 指标以小整数形式返回。
C/C++、COBOL 和 PL/I 支持 host-variable-array。 有关更多信息,请参阅 PL/I、C、C++ 和 COBOL 中的宿主变量数组。
- INTO DESCRIPTOR 描述符名称
- 标识一个 SQLDA,其中必须包含对零个或多个主机变量数组或缓冲区的有效描述,用于返回结果表中某列的值。
在处理FETCH语句之前,您必须在SQLDA中设置以下字段:
- SQLN用于指示SQLDA中提供的SQLVAR出现的次数。
- SQLABC用于指示为SQLDA分配的存储字节数。
- SQLD用于指示处理语句时SQLDA中使用的变量数量。
- SQLVAR的出现次数,用于指示宿主变量数组中元素的属性。 在每个代表数组的SQLVAR中:
- SQLTYPE 表示主机变量数组元素的数据类型。
- SQLDATA字段指向主机变量数组的第一个元素。
- 设置长度字段(SQLLEN和SQLLONGLEN)用于指示数组中单个元素的最大长度。
- SQLNAME——SQLNAME的长度必须设置为8,SQLNAME数据部分的前两个字节必须初始化为X'0000'。 第五和第六字节必须包含一个标志字段,第七和第八字节必须初始化为主机变量数组维度的二进制小整数(半字节)表示形式,以及相应的指示数组(如果指定了)。
将SQLDATA和SQLIND指针设置为相应数组的开头。 SQLDA必须具有足够的存储空间来容纳所有SQLVAR的出现。 每个SQLVAR的出现描述了一个主机变量数组或缓冲区,结果表中列的值将返回到该数组或缓冲区中。 如果结果表的任何一列是LOB,则必须为每个SQLVAR提供两个SQLVAR条目,并且SQLN必须设置为SQLVAR数量的两倍。 SQLD必须设置为大于或等于零且小于或等于SQLN的值。
备注 FETCH
- 目标分配:
- INTO子句中标识的或SQLDA中描述的第n个目标对应于游标结果表的第n列。 目标的数据类型必须与其对应的值相匹配。 如果数值,目标必须能够表示整个数值部分。 对于日期时间值,目标必须是字符串变量,且长度必须符合日期时间值的字符串表示形式中规定的最小长度。 当目标是一个宿主变量时,如果值为空,则必须指定一个指示变量。
任务按列表顺序分配。 根据 SQL语言元素中描述的规则,为每个目标分配任务。 如果目标数量少于该行中的值数量,则SQLCA的 SQLWARN3 字段设置为“W”。 如果目标数量超过结果列的数量,则不会发出警告。 如果目标是一个宿主变量,且值为空,则必须提供一个指示变量。 如果发生赋值错误,则不会将值赋给目标,也不会再向目标赋值。 任何已分配给目标的值仍保持分配状态。
如果同一赋值语句中包含多个赋值,则所有表达式将在执行赋值之前进行求值。 例如,在表达式中引用变量时,总是使用赋值语句中任何赋值之前的变量值。
通常情况下,您使用LOB定位器来分配和检索LOB列中的数据。 然而,由于兼容性规则,您也可以使用LOB定位器将数据分配给具有其他数据类型的目标。 有关定位器的更多信息,请参阅 《使用LOB定位器操作LOB时节省存储空间 》。
不能将没有时区值的时间戳分配给带有时区目标的时间戳。
数据的默认编码方案是绑定选项ENCODING中的值,该选项用于应用程序编码。 如果此语句与 LENGTH 或 SUBSTRING 等函数一起使用,且这些函数正在对 LOB 定位器进行操作,而定位器指定的 LOB 数据所采用的编码方案与 ENCODING 绑定选项不同,则会发生 LOB 物化和字符转换。 为避免LOB实体化和字符转换,请从 SYSIBM.SYSDUMMYA、 SYSIBM.SYSDUMMYE 或 SYSIBM.SYSDUMMYU 示例表中选取LOB数据。
- 对使用“WITH CONTINUE”和“CURRENT CONTINUE”条款的限制:
- 当使用 WITH CONTINUE 子句时, Db2 系统仅会为 BLOB、CLOB、DBCLOB 或 XML 数据类型的结果集列保留截断的数据,且仅当输出主机变量数据类型为适当的 LOB 数据类型时才会保留。
如果应用程序使用 FETCH WITH CONTINUE,并且在 FETCH 操作后仍有截断的数据,则应用程序在执行 FETCH CURRENT CONTINUE 之前无法对该游标执行任何中间操作。 如果对光标进行干预操作,则截断的数据将丢失。
FETCH CURRENT CONTINUE 不支持多行获取。 此外,FETCH CURRENT CONTINUE不支持截断的非LOB和非XML列。 如果这些非LOB和非XML列发生截断,则截断的数据将照常丢弃。
- 结果栏评估注意事项:
- 如果外部SELECT语句的SELECT列表中的算术表达式出现错误(除数为零或溢出)或数值转换错误,则结果为空值。 与任何其他无效值的情况一样,必须提供一个指示变量,而主变量保持不变。 然而,在这种情况下,指示变量被设置为 -2。 继续处理语句,就像错误没有发生一样。 (然而,此错误会导致SQLCODE为正。) 如果您不提供指示变量,SQLCA的SQLCODE字段将返回负值。 当遇到错误时,语句处理将终止。 宿主变量或后续变量没有赋值,但已赋值的变量仍保持赋值状态。
如果指定的宿主变量不足以容纳结果,则会返回警告,并在SQLCA中将W分配给 SQLWARN1。 如果提供了指标,则结果的实际长度将返回到与宿主变量关联的指标变量中。 FETCH操作可能无法返回警告。 这是优化带来的结果,例如使用系统临时表或阻塞。 返回的警告也可能适用于之前获取的行。 当返回一个日期时间值时,变量的长度必须足够大,以存储完整的值。 否则,将返回警告或错误。
- 当使用FETCH语句处理传递给加速器服务器的行集游标时,需要考虑以下事项:
- Db2 对传递给加速器服务器处理的行集查询提供有限支持。 Db2 仅支持高性能访问加速查询数据。 数据以行集的形式预先获取,并通过多行获取语句返回,在一个FETCH语句中返回多行数据。 以下限制适用于针对加速的行集游标执行的FETCH语句:
- 所有FETCH请求必须为行集提取。
- 所有FETCH请求必须指定 FOR n ROWS 子句。
- 所有FETCH请求必须指定相同的行集大小。
- 所有FETCH请求必须指定目标主机变量。 (FETCH操作必须有一个定位目标。)
- 光标定位:
- 光标有三个可能的位置:
- 争吵之前
- 在行或行集中
- 最后一排之后
当打开可滚动或不可滚动光标时,它位于结果表的第一行之前。 如果光标位于某行,则该行称为光标的当前行。 如果光标位于行集上,则这些行称为光标的当前行集。
UPDATE或DELETE语句中提到的光标必须位于行或行集上。 在FETCH语句中,光标只能位于行或行集上。
如果光标被声明为“静态敏感滚动”,则一行可能是一个空行 ,无法从中获取、更新或删除任何值。 敏感动态游标不存在孔,因为没有临时结果表。 更多信息,请参阅可滚动光标结果表中的“洞”。
对于可滚动的光标,错误发生后的光标位置取决于错误类型:
- 当尝试对更新或删除漏洞进行操作时,或者当检测到更新或删除漏洞时,光标将定位在漏洞上。
- 当尝试在文件末尾进行FETCH操作时,光标会定位在最后一行之后。
- 当在文件开始之前尝试FETCH操作时,光标会定位在第一行之前。
- 当错误导致光标位置无效时,例如当单行定位更新或定位删除错误导致回滚时,光标将关闭。
- 异常情况后的光标位置:
- 如果在执行获取操作时发生错误,光标的位置以及后续获取操作的结果将无法预测。 可能会出现错误,导致光标位置无效,在这种情况下,光标将关闭。
如果单个取操作指定的目标超出光标范围,则会发出警告(FETCH BEFORE或FETCH AFTER除外),光标会定位在结果表之前或之后,并且不会将值分配给宿主变量。
- 并发性和可滚动性:
- 如果当前光标行被锁定,则无法通过其他应用程序进程对其进行更新或删除。 除非在当前工作单元中,由于应用程序插入或更新而已锁定,否则在当前单元中,在以下情况下光标当前行不会被锁定:
- 隔离等级为UR,即
- 隔离等级为CS,
- 光标的结果表是只读的
- 绑定选项CURRENTDATA(NO)生效
当应用程序更注重查看更新行和新插入行,而不必查看已删除行时,动态可滚动光标非常有用。 CS的隔离级别应与动态滚动光标一起使用,以实现最大并发度。 指定RR或RS的隔离级别会严重限制表格的更新,从而违背了SENSITIVE DYNAMIC可滚动光标的初衷。 如果应用程序需要持续的结果表,则应使用隔离级别为CS的敏感静态可滚动光标。
- SENSITIVE STATIC SCROLL光标对数据库变化的敏感度:
- 当“敏感静态滚动”被启用时,以下规则适用:
- 为了使更新操作的结果在光标中“打开”后可见,更新操作必须是对光标执行的定位更新,或者必须对通过其他方法(即搜索更新、其他人的提交更新或同一进程中的其他光标更新)更新的行执行静态光标中的FETCH SENSITIVE。
- 另一个过程可以更新SELECT语句的基表,使当前值不再满足WHERE子句。 在这种情况下,当基础表中的值不符合WHERE子句时,就会存在一个“更新漏洞”,此时无法再通过游标访问该行。 当尝试获取已确定为更新漏洞的行时,不会返回任何值,并发出警告。
在“敏感静态滚动”光标下,更新孔仅在定位更新、定位删除和“获取敏感”操作期间识别。 每次定位更新、定位删除和FETCH SENSITIVE操作都会进行必要的测试,以确定是否存在更新漏洞。
- 若要在敏感静态滚动光标中显示删除操作的结果,则删除操作必须是针对光标执行的定位删除,或者必须在静态光标中针对通过其他方法(即搜索删除、其他人的已提交删除或同一进程中的其他光标删除)删除的行执行FETCH SENSITIVE。
- 另一个过程,或者甚至同一个过程,可能会删除SELECT语句的基表中的某一行,使得游标中的一行在基表中不再有对应的行。 在这种情况下,实际上存在一个“删除孔”,无法再通过光标访问该行。 当尝试获取已被识别为删除洞的行时,不会返回任何值,并发出警告。
在敏感静态滚动光标下,定位更新、定位删除和FETCH SENSITIVE操作期间会识别删除孔。
- 在光标打开后,敏感静态滚动光标的基表或表中插入的内容将不可见。
- LOB定位器:
- 当信息被检索到LOB定位器中,且无需在FETCH语句中保留定位器时,由于定位器资源有限,在发出另一个FETCH语句之前,最好先发出FREE LOCATOR语句。
- 隔离等级考虑:
- 语句的隔离级别(隐式或显式指定)会影响行集定位FETCH语句的结果。 当使用动态滚动光标时,如果隔离级别为UR,或者当应用程序从光标中获取行时,如果隔离级别为其他级别,则可以对光标所基于的表进行更改。 以下取景方向可能会出现这种情况:
- 以前的行集
- 借助动态可滚动光标和隔离级别UR,前一行的内容可能会受到表格中其他活动的影响。 之前符合游标条件并作为“先前”行集成员包含的行,在作为当前语句的行集的一部分实际返回之前,可能已被删除或修改。 为避免出现这种情况,请使用除UR以外的隔离级别。
- 当前行
- 通过动态可滚动光标,可以在返回给用户的行集之间添加额外的行。 隔离级别为“RR”时,这些行只能通过应用程序从光标处获取。 对于RR以外的隔离级别,其他应用程序可能会插入行,从而影响后续FETCH CURRENT ROWSET的结果。 为避免出现这种情况,请使用静态可滚动光标,而不是动态可滚动光标。
- 最后一行
- 借助动态可滚动光标和隔离级别UR,表中的其他活动可能会影响最后一行的内容。 之前符合游标条件并被作为“最后一”行集的成员包含在内的行,在作为当前语句的行集的一部分实际返回之前,可能已被删除或修改。 为避免出现这种情况,请使用除UR以外的隔离级别。
- 行数从相对值 -n (其中 -n 为负数)开始
- 借助动态可滚动光标和隔离级别UR,前一行的内容可能会受到表格中其他活动的影响。 之前符合游标条件并作为“先前”行集成员包含的行,在作为当前语句的行集的一部分实际返回之前,可能已被删除或修改。 为避免出现这种情况,请使用除UR以外的隔离级别。
- 行定位和行集定位 FETCH 语句交互:
- 下表显示了行定位和行集定位FETCH语句之间的交互。 该表基于以下假设:
- 表格 T1 有 15 行
- CURSOR CS1 声明如下:
DECLARE CS1 SCROLL CURSOR WITH ROWSET POSITIONING FOR SELECT * FROM T1;
- 已成功为游标 CS1 执行 OPEN CURSOR 语句,表中 FETCH 语句按其在表中的顺序执行。
表6。 行定位和行集定位FETCH语句之间的交互 FETCH 语句 光标位置 先取 光标位于第1行。 获取第一个行集 光标位于由第1行组成的1号行组上。 取前5行 光标位于由第1、2、3、4和5行组成的5号行组上。 获取当前行集 光标位于由第1、2、3、4和5行组成的5号行组上。 获取当前 光标位于第1行 取前5行 光标位于由第1、2、3、4和5行组成的5号行组上。 FETCH 或 FETCH NEXT 光标位于第2行。 获取下一行 光标位于由第3行组成的1号行组上。 取下3行中的下一行 光标位于由第4、5和6行组成的3号行组上。 获取下一行 光标位于由第7、8和9行组成的3号行组上。 获取最新 光标位于第15行。 获取最后两行的行集 光标位于由第14行和第15行组成的2号行组上。 取前一行 光标位于由第12行和第13行组成的2号行组上。 获取绝对值 2 光标位于第2行。 取三行,每行从绝对值2开始 光标位于由第2、3和4行组成的3号行组上。 取相对值 2 光标位于第4行。 取4行,每行2个,绝对值从2开始 光标位于由第2、3、4和5行组成的4号行组上。 取相对值 -1 光标位于第1行。 取两行,从第3行开始 光标位于由第3行和第4行组成的2号行组上。 取回行首,从相对4开始 光标位于由第7行和第8行组成的2号行组上。 优先获取 光标位于第6行。 取5行,从第13行开始 光标位于由第13、14和15行组成的3号行组上。 获取第一个行集 光标位于由第1、2、3、4和5行组成的5号行组上。 注意: 尽管之前的FETCH语句由于遇到EOF而只返回了3行,但 Db2 会记住之前的FETCH语句请求了5行。 - 使用“FOR n ROWS”子句和“FETCH FIRST n ROWS ONLY”子句时的注意事项:
- 在游标的 SELECT 语句、FETCH 语句或两者中,可以指定一个子句,说明所需的行数。 然而,这些条款会产生不同的效果:
- 在SELECT语句中, FETCH FIRST n ROWS ONLY子句控制光标可访问的最大行数。 当FETCH语句试图检索超出SELECT语句中的FETCH FIRST n ROWS ONLY子句中指定的行数时,就会发生数据结束条件。
- 在FETCH语句中, FOR n ROWS子句控制单个FETCH语句返回的行数。
这两个条款都可以具体说明。
参考列将更新:
如果游标使用FETCH语句来检索稍后更新的列,则在选择列时指定FOR UPDATE OF。 然后在后续的UPDATE或DELETE语句中指定WHERE CURRENT OF。 这些条款阻止了 Db2 通过更新列的索引进行访问,否则可能导致 Db2 多次读取同一行。
更多信息,请参阅更新之前检索的数据。
- 行集定位FETCH语句的诊断信息:
- 一行集游标中的FETCH语句可能遇到零个、一个或多个条件。 如果当前光标位置对于获取方向无效,则会发出警告并终止语句。 如果在获取行期间出现警告或非终止性错误(例如绑定错误),则继续处理。 在这种情况下,FETCH语句会返回一条摘要信息,而GET DIAGNOSTICS语句则可提供每条提取行的附加信息。 使用GET DIAGNOSTICS语句获取FETCH语句中遇到的所有条件的相关信息。 更多信息请参阅 “获取诊断”声明。SQLCA返回一些从行集游标中获取数据时发现的错误和警告信息。 当遇到数据末尾或终止条件时,处理过程将停止。 在行集游标执行完每个FETCH语句后,信息将通过SQLCA返回给程序。 SQLCA的设置如下:
- SQLCODE包含SQLCODE。
- SQLSTATE包含SQLSTATE。
- SQLERRD1 如果光标位于结果表的最后一行,则 包含结果表的行数。 SQLERRD2
- SQLERRD3 包含返回的实际行数。 如果 SQLERRD3 小于请求的行数,则表明发生了错误或数据结束的情况。
- SQLWARN标志用于表示处理FETCH语句时累积的所有警告。
请看下面的例子,其中用一条FETCH语句获取了10行数据。
- 示例 1
- 假设在 5th 行中检测到一个错误。 SQLERRD3 返回的4行中,SQLSTATE设置为22537,SQLCODE设置为-354。 这些信息也可以从GET DIAGNOSTICS报表中获得(返回的信息由连接的服务器生成,不同服务器可能返回的信息不同)。 例如:
GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER; -- Results of the statement: -- num_rows = 4 and num_cond = 1 (1 condition)
GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 22537, sqlcode = -354, and row_num = 5
- 示例 2
- 假设在 6th 行检测到数据结束条件,并且光标对更新没有立即的敏感性。 SQLERRD3 返回的5行中,SQLSTATE设置为02000,SQLCODE设置为+100。 这些信息也可以从“获取诊断”报告中获取。 例如:
GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER; -- Results of the statement: -- num_rows = 5 and num_cond = 1 (1 condition)
GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 02000, sqlcode = 100, and row_num = 6
- 示例 3
- 假设在 5th 行中检测到绑定错误,则记录该错误并继续处理。 此外,假设在 8th 行中检测到数据结束条件。 SQLERRD3 返回的7行中,SQLSTATE设置为02000,SQLCODE设置为+100。 执行FETCH语句的完成处理,并记录发生的绑定错误。 绑定错误会记录一个额外的SQLCODE。 SQLCODE设置为-354,SQLSTATE设置为01668。 使用GET DIAGNOSTICS语句来确定发生了什么。 例如:
GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER; -- Results of the statement: -- num_rows = 7 and num_cond = 3 (3 conditions)
GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 01668, sqlcode = -354, and row_num = 0
GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE, :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 02000, sqlcode = 100, and row_num = 0
GET DIAGNOSTICS CONDITION 3 :sqlstate = RETURNED_SQLSTATE, :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 22003, sqlcode = -302, and row_num = 5
在某些情况下,如果提供了指示变量, Db2 会返回警告;如果没有提供指示变量,则会返回错误。 这些错误可以被视为数据映射错误,如果提供了指示变量,则会导致警告。
- 如果提供了指示变量, Db2 会向用户返回所有行,并标记指示变量中的错误。 SQLCODE和SQLSTATE包含上次数据映射错误的警告。 GET DIAGNOSTICS语句可用于检索所有已发生的数据映射错误的信息。
- 如果提供部分或不提供指示变量,则返回所有行,直到检测到第一个没有指示变量的数据映射错误。 成功获取的行被返回,并在必要时设置SQLSTATE、SQLCODE和SQLWARN标志。 (SQLCODE可以为0或正值)。
如果发生数据映射错误,光标定位可能会成功。 在这种情况下,光标位于遇到数据映射错误的行集上。
请考虑以下示例,这些示例试图通过一个FETCH语句获取10行数据。
- 示例 1
- 假设已为第1列的返回值提供了指标,但未为第2列提供。 5th 行第1列的数据映射错误(+802), 7th 行第2列的数据映射错误(-802,因为第2列没有提供指示器)。 SQLERRD3 对于返回的6行,将6设置为6,SQLSTATE和SQLCODE设置为从 行中获取的错误。 7th 5th 行第1列的指示变量表明发现数据映射错误。 这些信息也可以从GET DIAGNOSTICS诊断报告中获取,例如:
GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER; -- Results of the statement: -- num_rows = 6 and num_cond = 2 (2 conditions)
GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 01519, sqlcode = +802, and row_num = 5
光标位置未知。GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 22003, sqlcode = -802, and row_num = 7
- 示例 2
- 假设提供了空值指示符,第3行和第5行为空,其他请求的行中存在数据。 SQLERRD3 设置为10,表示已完成10次抓取,并已返回10行请求的信息。 实际上,八行包含数据。 对于两行,指示变量设置为指示没有返回这些行的数据。 SQLSTATE设置为02502,SQLCODE设置为+222,第3行和第5行的所有空值指示符都设置为 -3 ,表示检测到漏洞。 这些信息也可以从GET DIAGNOSTICS诊断报告中获取,例如:
GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER; -- Results of the statement: -- num_rows = 10 and num_cond = 2 (2 conditions)
GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 02502, sqlcode = +222, and row_num = 3
如果一行中任何变量的空值指示符为空,则会发生错误。GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE, :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER; -- Results of the statement: -- sqlstate = 02502, sqlcode = +222, and row_num = 5
- SQLCA使用情况总结:
- 对于多行获取,SQLCA的字段设置如下:
条件 操作:SQLCA字段中存储的结果值 错误 数据 SQLSTATE SQLCODE SQLERRD3 否1 返回所有请求的行 00000 0 请求的行数 否1 返回所请求行子集的数据,数据结束 02000 +100 行数 否1 返回所有请求的行 sqlstate(2) sqlcode(2) 请求的行数 是1 成功获取的返回行 sqlstate(3) sqlcode(3) 行数 是1 成功获取的返回行 sqlstate(4) sqlcode(4) 行数 注:- 在所有情况下都可以设置SQLWARN标志,即使没有其他警告或错误指示。 警告标志是处理多行获取时设置的警告标志的集合。
- sqlcode是最后一个正SQLCODE,sqlstate是相应的SQLSTATE值。
- 数据库服务器检测到错误。 sqlcode是遇到的第一个负SQLCODE,sqlstate是相应的SQLSTATE值。
- 客户端检测到错误。 sqlcode是遇到的第一个负SQLCODE,sqlstate是以下SQLSTATEs之一:22002、22008、22509、22518或55021。
- 为错误条件提供指示变量:
- 如果外部SELECT语句的SELECT列表中的算术表达式出现错误(除数为零或溢出)或数值转换错误,则结果为空值。 与任何其他无效值的情况一样,必须提供一个指示变量,而主变量保持不变。 然而,在这种情况下,指示变量被设置为 -2。 继续处理语句,就像错误没有发生一样。 (然而,此错误会导致SQLCODE为正。)
如果您不提供指示变量,SQLCA的SQLCODE字段将返回负值。 当遇到错误时,语句处理将终止。 宿主变量或后续变量没有赋值,但已赋值的变量仍保持赋值状态。 此外,当在FETCH定位的行集中检测到该行有洞时,应用程序提供的所有指示器都会返回一个 -3 ,并且不会返回该行的值。 如果检测到漏洞,且应用程序未提供至少一个指示变量,则语句处理将终止。
- 其他语法和同义词:
- USING DESCRIPTOR(使用描述符)可以指定为INTO DESCRIPTOR(进入描述符)的同义词。
例子 FETCH
- 示例 1
- FETCH语句将SELECT语句的结果提取到应用程序变量DNUM、DNAME和MNUM中。 当没有可提取的行时,将返回未找到状态。
EXEC SQL DECLARE C1 CURSOR FOR SELECT DEPTNO, DEPTNAME, MGRNO FROM DSN8C10.DEPT WHERE ADMRDEPT = 'A00'; EXEC SQL OPEN C1; DO WHILE (SQLCODE = 0); EXEC SQL FETCH C1 INTO :DNUM, :DNAME, :MNUM; END; EXEC SQL CLOSE C1;
- 示例 2
- 关于带有动态可滚动光标的FETCH语句示例,请参见示例8。
- 示例 3
- 使用光标获取结果表 C1 的最后5行 C1:
FETCH ROWSET STARTING AT ABSOLUTE -5 FROM C1 FOR 5 ROWS INTO DESCRIPTOR :MYDESCR;
- 示例 4
- 从光标 CURS1 的第10行开始获取6行,并将数据放入三个主机变量数组中:
或者,可以在INTO DESCRIPTOR子句中指定描述符,其中SQLDA中的信息反映宿主变量数组的数据类型:FETCH ROWSET STARTING AT ABSOLUTE 10 FROM CURS1 FOR 6 ROWS INTO :hav1, :hva2, :hva3;
FETCH ROWSET STARTING AT ABSOLUTE 10 FROM CURS1 FOR 6 ROWS INTO DESCRIPTOR :MYDESCR;
- 示例 5
假设已定义了以下数组类型、数组变量和表。
CREATE TYPE INTARRAY AS INTEGER ARRAY[100]; CREATE TABLE T1 (COL1 CHAR(10), COL2 INT);
将数组变量用作FETCH语句的输出目标。 数组变量在FETCH语句的INTO子句中指定。
CREATE PROCEDURE PROCESSINTARRAY (OUT INTOUTARRAY INTARRAY) BEGIN DECLARE INTA INTARRAY; DECLARE INTB INTARRAY; DECLARE INTV INTEGER DEFAULT 1; DECLARE STMT CHAR(100); DECLARE C2 CURSOR FOR S1; -- -- Initialize the array -- SET INTA = ARRAY[1,INTEGER(2),3+0,4,5,6] ; -- -- Use dynamic SQL with an array parameter marker and a parameter marker -- containing the index to retrieve the value from the array parameter. -- The array is referenced in a predicate. -- SET STMT = 'SELECT COL1 FROM T1 WHERE COL2 = CAST(? AS INTARRAY)[?]'; PREPARE S1 FROM STMT; OPEN C2 USING INTA, INTV; FETCH C2 INTO INTB ; -- INTB is an array variable that is used -- as a target for the fetch statement. CLOSE C2; SET INTOUTARRAY=INTB; END