SELECT INTO 语句

SELECT INTO语句生成的结果表最多包含一行。 该语句将该行中的值赋给变量。 如果表为空,则语句不会为主变量或全局变量赋值。

调用 SELECT INTO

此语句只能嵌入在应用程序中。 这是一个无法动态准备的可执行语句。

授权 SELECT INTO

以下定义的特权套装必须至少包含以下一项:
  • 语句中确定的每个表和视图的 SELECT 权限
  • 声明中确定的每张桌子和每处景观的所有权
  • 读取语句中标识的任何全局变量的权限
  • 对声明中确定的任何全局变量的所有权
  • DBADM 数据库权限(仅限表格)
  • DATAACCESS 权限
  • SYSADM 权限
  • SYSCTRL权限(仅限目录表)

如果SELECT INTO语句包含SQL数据更改语句,则权限集还必须至少包含与该SQL数据更改语句在表或视图中关联的权限(INSERT、UPDATE或DELETE)。

更改开始对于赋值给全局变量或数组元素的全局变量,权限集必须至少包含以下内容之一:更改结束

更改开始
  • 可变WRITE权限
  • 可变的所有权
  • DATAACCESS 权限
  • SYSADM 权限
更改结束

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

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

权限设置:

更改开始如果语句嵌入到应用程序中,权限集就是软件包所有者所拥有的权限。 如果语句是动态编写的,则权限集由生效的动态规则行为(运行、绑定、定义或调用)决定,并在动态规则行为和授权检查中进行总结。 有关这些行为的更多信息,包括决定这些行为的 DYNAMICRULES 绑定选项值列表,请参阅授权 ID 和动态 SQL更改结束

语法 SELECT INTO

阅读语法图跳过可视化语法图WITH,公共表表达式 select-clause1 INTO ,目标变量数组变量[ 数组索引] from-clause where 子句 分组子句 having-clause order-by-clauseoffset-clausefetch-子句2isolation-clauseSKIP LOCKED DATAQUERYNO整数
目标变量
阅读语法图跳过可视化语法图全局变量名主机变量名SQL参数名称SQL变量名过渡变量名
注意:
  • 1 选择子句不能同时引用系统周期临时表和启用存档的表。
  • 2 同一条款不得重复出现。

描述 SELECT INTO

更改开始FL 500 结果表是通过按以下顺序逻辑评估 isolation-clausefrom-clausewhere-clausegroup-by-clausehaving-clauseorder-by-clauseoffset-clausefetch-clauseselect-clause 而得出的。 根据 Db2 子系统选择的计划,实际顺序可能略有不同。 有关这些条款的说明,请参阅查询下的主题。更改结束

语句中确定的表或视图可以存在于当前服务器上,也可以存在于当前服务器可以与之建立连接的任何 Db2 子系统中。

WITH common-table-expression
有关指定公共表表达式的信息,请参阅公共表表达式
INTO 目标变量数组变量 [数组索引 ]
确定一个或多个输出值的目标。 INTO子句中的目标数量必须与要分配的值数量相等。 结果行中的第一个值分配给列表中的第一个目标,第二个值分配给第二个目标,以此类推。 在INTO子句中,目标变量不能被指定多次。 根据 “任务和比较” 中描述的规则,按照列表中的顺序为每个目标分配任务。

如果目标数量少于结果列的值数量,则将值“W”分配给SQLCA的 SQLWARN3 字段。

如果任何赋值操作出错,则不会将值赋给目标,也不会再向指定目标赋值。 任何已分配的值将保持不变。

global-variable-name
标识作为赋值目标的全球变量。
主机变量名
标识作为赋值目标的主变量。 对于LOB输出值,目标可以是常规的主变量(如果足够大)、LOB定位变量或LOB文件引用变量。
SQL参数名称
标识作为赋值目标的参数。
SQL变量名
标识作为赋值目标的SQL变量。 SQL变量在使用前必须声明。
更改开始过渡变量名更改结束
更改开始标识过渡表中要更新的列。 过渡变量名必须标识触发器主题表中的一列,可选择使用相关名称来限定,以标识新值。更改结束
数组变量 [数组索引]
指定作为赋值目标的数组元素。

如果语句中也指定了公共表表达式 ,则不能将数组元素指定为赋值的目标。

数组变量
指定一个数组变量。
[数组索引 ]
用于指定数组中哪个元素是赋值目标。

对于普通数组,数组索引表达式必须可转换为整数,且不能为空值。 索引值必须在1和数组定义的最大基数之间。

对于关联数组,数组索引表达式必须可转换为关联数组的索引数据类型,且不能为空值。

数组索引不能为:

  • 引用当前日期、当前时间或当前时间戳特殊寄存器的表达式
  • 非确定性函数
  • 由外部动作定义的功能
  • 用MODIFIES SQL DATA定义的功能
  • 序列表达式
  • 不在标量全选中的列。

变量的数据类型必须与赋给它的值相匹配。 如果数值是数字,则变量必须能够表示该数值的一个整数部分。 对于日期或时间值,变量必须是一个字符串变量,其最小长度如赋值和比较中定义。

根据赋值和比较中描述的规则,对变量进行赋值。 任务按列表顺序分配。

如果SELECT INTO语句的SELECT列表中的算术表达式出现错误(除数为零或溢出)或数值转换错误,则结果为空值。 与任何其他无效值的情况一样,必须提供一个指示变量,且主变量保持不变。 然而,在这种情况下,指示变量被设置为 -2。 继续处理语句,就像错误没有发生一样。 (然而,此错误会导致SQLCODE为正。) 如果您不提供指示变量,SQLCA的SQLCODE字段将返回负值。 当遇到错误时,语句处理将终止。

如果发生错误,则不会为变量或后续变量赋值,但已赋值的变量仍保持赋值状态。

如果结果表有多行,则可能会发生错误,导致变量被赋值。 如果为变量赋值,则作为值来源的行将无法定义且不可预测。

跳过已锁定的数据
当其他事务对行持有不兼容的锁时,指定跳过该行。 这些行可以属于语句中指定的任何已访问表。 仅当隔离CS或RS生效时,才能使用跳过锁定数据,且仅适用于行级或页级锁定。

如果指定的隔离级别为可重复读取(WITH RR)或未承诺读取(WITH UR),则跳过锁定数据(SKIP LOCKED DATA)将被忽略。

QUERYNO 整数
指定在EXPLAIN输出和跟踪记录中用于此SQL语句的编号。 该数字用于计划表中 QUERYNO 列,其中包含有关此 SQL 语句的信息。 这个数字也用于 SYSIBM.SYSSTMT 和 SYSIBM.SYSPACKSTMT 目录表的QUERYNO列。

如果省略该子句,则与SQL语句关联的数字就是预编译期间分配的语句编号。 因此,如果应用程序被修改并预编译,那么语句编号可能会改变。

使用QUERYNO子句为程序中的SQL语句分配唯一编号很有帮助:

  • 为了简化访问路径选择优化提示的使用
  • 用于将SQL语句文本与计划表中的EXPLAIN输出相关联

有关启用和使用优化提示的更多信息,请参阅影响访问路径选择

备注 SELECT INTO

目标分配
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数据。
如果结果表为空
如果表为空,则语句将+100赋给SQLCODE,将'02000'赋给SQLSTATE,并且不向宿主变量或全局变量赋值。
插入的行数
如果游标的 SELECT INTO 语句包含 SQL 数据更改语句,则 SELECT INTO 操作会将 SQLERRD(3) 设置为插入的行数。
更改开始对抵消条款的考虑更改结束
更改开始
  • 当查询可能产生多行结果时, 偏移子句可用于 SELECT INTO 语句。
  • 要影响返回的行,可以使用 order-by子句。 当您指定了按……排序子句时,结果中的行会被排序,指定的行数会被跳过,并返回第一行。 如果未指定 fetch子句 ,且结果表包含多行,则会发生错误。
更改结束
更改开始取词条款考虑因素更改结束
更改开始FL 500
  • 当查询可能产生多行结果时, 取语句可用于 SELECT INTO 语句。 指定FETCH FIRST 1 ROW ONLY表示最多只能检索一行,而不管结果表中包含多少行。
  • 使用 fetch子句将结果表明确限制为单行,为SELECT INTO语句提供了与可能返回多行的查询一起使用的方法。 当您知道只想检索一行时,使用该子句有助于避免使用光标。 要影响返回的行,可以使用 order-by子句。 当您指定了排序子句时,结果中的行会按顺序排列,然后返回第一行。 如果未指定 fetch子句 ,且结果表包含多行,则会发生错误。
更改结束

例子 SELECT INTO

示例 1
DSN8C10.EMP 中的最高工资存入主变量 MAXSALRY。
   EXEC SQL SELECT MAX(SALARY)
     INTO :MAXSALRY
     FROM DSN8C10.EMP;
示例 2
DSN8C10.EMP中 528671号员工的行放入EMPREC主机结构中。
   EXEC SQL SELECT * INTO :EMPREC
     FROM DSN8C10.EMP
     WHERE EMPNO = '528671'
   END-EXEC.
示例 3
DSN8C10.EMP中 528671号员工的行放入EMPREC主机结构中。 假设此行稍后会更新,因此在查询执行时应该锁定。
   EXEC SQL SELECT * INTO :EMPREC
     FROM DSN8C10.EMP
     WHERE EMPNO = '528671'
     WITH RS USE AND KEEP EXCLUSIVE LOCKS
   END-EXEC.
示例 4
使用 SELECT INTO 语句,将表 T1 中的值 INTCOL1 检索到数组 MYINTARRAY1 中的元素,该元素由表达式 INTCOL2+MYINTVAR+1 的值索引。
SELECT INTCOL1 INTO MYINTARRAY1[INTCOL2+MYINTVAR+1]
 FROM T1
 WHERE INTCOL1 = MYINTARRAY1[INTCOL2] ;