PREPARE 语句
PREPARE语句根据语句的字符串形式创建可执行的SQL语句。 字符串形式称为语句字符串。 可执行形式称为预编译语句。
调用 PREPARE
此语句只能嵌入在应用程序中。 这是一个无法动态准备的可执行语句。 Java™中不能指定。
授权 PREPARE
授权规则是为动态准备 PREPARE 语句指定的 SQL 语句而定义的。 例如,请参阅查询 ,了解在准备 SELECT 语句时适用的授权规则。
仅使用EXPLAIN权限准备的语句无法执行,只能获取该语句的描述性信息。
语法 PREPARE
属性字符串
- 1 同一条款不得重复出现。 如果未指定选项,则使用关联语句中为相应选项指定的默认值。
- 2 FOR SINGLE ROW或FOR MULTIPLE ROWS子句仅适用于INSERT或MERGE语句。
- 3 原子或非原子继续SQLEXCEPTION子句只能用于INSERT语句。
可容纳性:
可退货:
行集定位:
并发访问解决
描述 PREPARE
- statement-name
- 指定已准备的语句。 如果名称标识了已存在的预定义语句,则该预定义语句将被销毁。 此名称不能标识作为打开游标的 SELECT 语句的已准备语句。
- INTO
- 如果您使用 INTO,并且 PREPARE 语句成功执行,则有关已准备语句的信息将放置在描述符名称指定的 SQLDA 中。 例如,以下PREPARE语句等效于发出PREPARE和DESCRIBE OUTPUT语句:
也就是说,前面的示例相当于以下PREPARE和DESCRIBE OUTPUT语句的组合:EXEC SQL PREPARE S1 INTO :SQLDA FROM :V1;
EXEC SQL PREPARE S1 FROM :V1; EXEC SQL DESCRIBE S1 INTO :SQLDA;
- 描述符名称
识别 SQLDA。 对于REXX以外的语言,必须设置SQLN以指示SQLVAR的出现次数。 更多信息,请参阅确定需要多少个SQLVAR。
有关 SQLDA 中信息的更多信息,请参阅 DESCRIBE OUTPUT 返回的 SQLDA 内容。
参见 有关如何在C语言中描述描述符名称的信息, 请参见在C或C++中识别SQLDA。
- USING
- 指示在INTO使用时,为SQLDA中的每个SQLNAME变量分配什么值。 如果请求的值不存在,SQLNAME 设置为长度为 0。
- 名称
- 指定列的名称。 这是缺省值。
- 标签
- 为列添加标签。 (列标签由LABEL语句定义。)
- 任何
为列添加标签。 如果列没有标签或标签是长度为0的字符串,则使用列名称。
- 资产和操作位置
- 指定列的标签和名称。 在这种情况下,每列需要出现两到三次SQLVAR,具体取决于结果表是否包含不同的类型,以容纳额外的信息。 为了指定SQLVAR数组的扩展,请将SQLN设置为 2×n 或 3×n ,其中 n 是所描述对象中的列数。 对于每个列,SQLVAR 的前n个出现 (即SQLVAR的基本条目)包含列名。 SQLVAR的第二个或第三个n次出现 (即扩展的SQLVAR条目)包含列标签。 如果没有明确的类型,则标签会返回到第二组SQLVAR条目中。 否则,标签将返回到第三组SQLVAR条目中。
REXX SQLDA 不包含 SQLN 字段,因此您无需为 REXX 程序设置 SQLN。
- 属性 attr-host-variable
- 指定在关联语句中未指定相应属性时生效的属性。 如果属性被指定为关联语句的一部分,则使用这些属性来代替PREPARE语句中指定的相应属性。 反过来,如果在SELECT语句的PREPARE中指定了属性,则将使用这些属性,而不是在DECLARE CURSOR语句中指定的相应属性。
attr-host-variable 必须根据声明字符串变量的规则,标识程序中描述的主机变量。 attr-host-variable 必须是一个长度属性不超过 32758 字节的字符串变量(固定长度或可变长度)。 从主变量的值中减去前导和尾随空格。 宿主变量必须包含有效的属性字符串。
可以使用指示变量来指示属性是否在PREPARE语句中实际提供。 因此,无论是否需要指定属性,应用程序都可以使用相同的PREPARE语句。
属性字符串中可指定的选项如下:
- 灵敏、不灵敏、静态灵敏或动态灵敏
- 指定光标对结果表下方行中的插入、更新或删除操作的敏感度。 光标的灵敏度决定了 Db2 能否将结果行转换为临时表。 缺省值为 ASENSITIVE。
- ASENSITIVE
- 指定光标应尽可能灵敏。 定义为“灵敏”的光标将要么不灵敏,要么动态灵敏;它不会静态灵敏。 有关如何使用GET DIAGNOSTICS语句或SQLCA将光标的有效灵敏度返回到应用程序的信息,请参阅 OPEN语句。
光标的灵敏度是选择访问路径的一个因素。 请明确说明您需要的灵敏度级别,而不是使用“ASENSITIVE”(无灵敏度)。
- INSENSITIVE
- 指定光标对结果表下方行的插入、更新或删除操作不敏感。 因此,结果表的大小、行的顺序以及每行的值在打开游标后都保持不变。 此外,光标为只读。 SELECT语句或PREPARE语句的属性字符串不能包含FOR UPDATE子句,光标不能用于定位更新或删除。
- SENSITIVE
- 指定光标对结果表具体化后数据库所做的更改具有敏感性。 光标始终对使用同一光标进行的定位更新和删除敏感。 但是,如果游标被定义为“敏感动态”或“敏感静态”, 则选择语句中不能包含SQL数据更改语句。 当某行的当前值不再满足选择语句或语句名称时,该行将不再通过光标显示。 当从基础表中删除结果表中的一行时,通过光标将无法再看到该行。
此外,光标对光标外数值的变化(即其他光标或其他应用程序进程所做的更改)敏感。 如果 Db2 无法将光标外的更改显示给光标,则在打开光标时出现错误。 光标是否对光标外部的变化敏感取决于光标是否处于动态或静态状态,以及是否使用了敏感或非敏感取值语句。
光标是否对新插入的行敏感取决于光标是否处于动态或静态状态。 默认值为“动态”。
- 动态
- 指定游标的查询结果表是动态的,即在打开游标后,当基础表中插入或删除行时,结果表的大小会发生变化,行的顺序也会改变。 通过同一应用程序进行的插入、删除和更新操作会立即显示出来。 其他应用程序进程所做的插入、删除和更新在提交后可见。
所有敏感动态游标的 FETCH 语句都会受到该游标所做的更改、同一应用程序进程中其他游标所做的更改以及其他应用程序进程所做的已提交更改的影响。
如果无法使用敏感动态光标,则返回错误。 对于敏感的动态光标,不得指定 FETCH FIRST n ROWS ONLY子句和OFFSET子句(无论是在光标最外层的fullselect中,还是在准备属性中)。
- 静态
- 指定结果表的行顺序和大小是固定的。 光标打开且行显示后,结果表的尺寸不会增加。 行顺序在结果表生成时确定。 插入基础表的行不会添加到游标的输出表中,无论插入方式如何。 如果更新了已实现的行中的 ORDER BY 子句中的列,则结果表中的行不会移动。
光标外部的更改是否对光标可见取决于与敏感静态光标一起使用的 FETCH 类型。 更多信息,请参阅 “关于敏感静态光标使用的FETCH语句的注意事项 ”。
在select语句或敏感静态游标的语句名称的WHERE子句中使用非确定性函数(内置或用户定义)可能会导致误导性结果。 这是因为 Db2 构建了一个临时结果表,并从该表中检索行以用于INSENSITIVE FETCH语句。 当 Db2 处理敏感的FETCH语句时,将从基础表中提取行,如果谓词包含不相关的子查询,则重新评估谓词。 使用非确定性的函数可能会导致重新评估的查询产生不同的结果,从而使该行不再被视为匹配项。
如果指定了“敏感静态”,但无法使用敏感静态光标,则返回错误。
如果将“灵敏度”、“不灵敏度”、“动态灵敏度”或“静态灵敏度”指定为“属性”子句的一部分,则必须指定“滚动”。
- 滚动或非滚动
- 指定光标是否可滚动。
- SCROLL
- 指定光标可滚动。
- 无需滚动
- 指定光标不可滚动。
- WITHOUT RETURN 或者 WITH RETURN
- 指定游标的输出表是否用作存储过程返回的结果集。 如果指定了语句名称 ,则默认值为语句的对应准备属性。 否则,默认值为 WITHOUT RETURN。
- WITHOUT RETURN
- 指定游标的结果表不打算用作将从过程返回的结果集。
- WITH RETURN
- 指定游标的结果表将用作存储过程返回的结果集。 只有在存储过程的源代码中包含PREPARE语句时,WITH RETURN才有效。 在其他情况下,预编译器可能会接受该条款,但该条款无效。
当使用 WITH RETURN TO CALLER 子句声明的游标在程序或例程结束时保持打开状态时,该游标定义了程序或例程的结果集。 使用CLOSE语句关闭游标,游标并非程序或例程的结果集。 虽然 Db2 会自动关闭任何未使用WITH RETURN子句声明的游标,但建议使用CLOSE语句来提高应用程序的可移植性。
对于不可滚动的游标,结果集包括从当前游标位置到结果表末尾的所有行。 对于可滚动光标,结果集由结果表的所有行组成。
- TO CALLER
- 指定光标可以将结果集返回给过程调用方。 调用者是执行SQL CALL语句的程序或例程,该语句调用包含PREPARE语句的过程。 例如,如果调用者是一个过程,则结果集将返回给该过程。 如果调用方是客户端应用程序,则结果集将返回给客户端应用程序。
如果语句包含在过程的源代码中,则 WITH RETURN TO CALLER 指定游标可用作结果集游标。 当要从存储过程返回游标的查询结果表时,可以使用结果集游标。 指定“呼叫者”是可选的。
在其他情况下,该条款会被忽略,光标不能用作结果集光标。
- TO CLIENT
- 指定光标可以将结果集返回给客户端应用程序。 任何中间嵌套过程都看不到这个光标。 如果函数或触发器调用该过程(直接或间接),则结果集无法返回给客户端,游标将在过程结束后关闭。
- 排定位置
- 指定是否可以在FETCH语句中以行集的形式访问此游标的行数据。
- 无行距定位
- 指定光标只能用于行定位FETCH语句。
- 行位置
- 指定此光标可用于行集定位或行定位FETCH语句
偏移条款
FL 5 00 偏移子句指定从中间结果表的开头开始跳过的行数。 offset-row-count 是一个常量,指定一个数值,可以是正数或零。 如果值不是BIGINT类型,则将其转换为BIGINT类型。 起始行的偏移量为零(而非1)。 offset-row-count 不能为空值。
对于敏感的动态光标,最外层的全选不能指定偏移子句。
更多信息,请参阅偏移条款。
取语句
FL 500 取语句指定了可检索的最大行数。 fetch-row-count 是一个常量,指定一个数值,可以是正数或零。 如果值不是BIGINT类型,则将其转换为BIGINT类型。 fetch-row-count 不能为空值。
对于敏感的动态游标,最外层的fullselect不能指定 fetch子句。
当只需要有限数量的行时,使用 fetch子句可以提高查询潜在大结果集的性能。 如果指定了子句,则检索的行数不会超过 n ,其中 n 是整数值。 尝试获取n+1 行与正常结束数据的方式相同。
更多信息,请参阅 fetch子句。
- 只读条款
- 声明结果表是只读的,因此光标不能在已定位的UPDATE和DELETE语句中引用。
- 更新条款
- 标识可在后续UPDATE语句中更新的列。 每个列必须是无条件的,并且必须标识在fullselect的第一个FROM子句中标识的表或视图的列。 如果fullselect的结果表是只读的,则不能指定该子句。 如果创建的临时表在select语句的第一个FROM子句中被引用,则也不必指定该子句。
如果指定了子句而没有列出列,则可以更新的列包括在 fullselect 的第一个 FROM 子句中标识的表或视图的所有可更新列。
- 优化子句
- 请求对选择语句进行特殊优化。 如果省略该子句,则优化基于结果表的所有行都将检索到的假设。 如果指定了子句,则优化基于以下假设:检索的行数不会超过 n ,其中 n 是整数值。 该条款不限制可获取的行数,也不影响性能以外的其他结果。
- 隔离条款
- 指定执行选择语句时的隔离级别。 参见隔离条款。
- 并发访问解决
- 指定用于select语句的并发访问解析类型。 并发访问决议中的每个子句只能指定一次。 每个PREPARE语句只能指定一个子句。 如果未指定任何条款,则锁定语义取决于语句的其他属性。
- SKIP LOCKED DATA
- 指定跳过其他事务持有不兼容锁定的数据。 查看 “跳过锁定数据 ”。
- USE CURRENTLY COMMITTED
- 指定当数据正在更新时, Db2 可以使用当前提交的数据版本。 当前已承诺仅适用于以下情况:
- 正在访问的表在通用表空间中定义
- 访问权限取决于隔离子句中指定的游标稳定性(CS)或读取稳定性(RS)的选定语句:
- 当读取事务访问被插入事务锁定的记录时,隔离级别(CS)和隔离级别(RS)都适用。
- 当读取事务访问被删除事务锁定的记录时,仅当 CURRENTDATA(NO) 有效时,才适用 ISOLATION(CS)。
如果用于其他语境,则忽略当前已提交的内容。
当指定此条款时,子系统参数EVALUNC的设置将适用。 如果该行符合条件,则根据此条款决定访问该行还是跳过该行。
当指定了此子句且子系统参数SKIPUNCI生效时,PREPARE将使用此子句的指定。 更多信息请参阅“备注”部分。
当指定此条款且选择了不支持多种XML版本的XML数据时, Db2 无法确定数据是否已提交。 在这种情况下, Db2 在访问数据时使用WAIT FOR OUTCOME行为。
- WAIT FOR OUTCOME
- 指定当遇到正在更新或删除的数据时, Db2 等待提交或回滚。 正在插入的行不会被跳过。
- FOR MULTIPLE ROWS 或者 FOR SINGLE ROW
- 指定是否为动态插入或合并语句提供可变数量的行,以及主机变量数组。
- 多行
- 指定在执行语句时,可以为正在准备的语句提供多行主机变量数组。 FOR MULTIPLE ROWS 只能用于 INSERT 或 MERGE 语句。
- 单排
- 指定在执行语句时,正在准备的语句的多个行不能使用主机变量数组。 FOR SINGLE ROW 只能用于 INSERT 或 MERGE 语句。
- 是否为原子型继续 SQLEXCEPTION
- 指定是否将所有行作为原子操作插入。 此子句仅适用于动态INSERT语句。
- ATOMIC
- 指定如果任何一行插入失败,则所有插入对数据库所做的更改(包括成功插入所做的更改)都将撤销。 这是缺省值。
- 非原子继续SQLEXCEPTION
- 指定无论该行中的任何特定插入是否失败,INSERT语句都不会撤销其他行成功插入对数据库所做的任何更改,并且会尝试插入后续行。 然而,最小原子性至少是单个插入操作(即部分插入操作无法完成),包括因INSERT语句而激活的任何触发器。
如果INSERT语句包含在SELECT语句中,则不得指定此条款。
在准备MERGE语句时,原子性仅在MERGE语句本身中指定。
WITHOUT EXTENDED INDICATORS 或者 WITH EXTENDED INDICATORS
指定在执行INSERT、MERGE或UPDATE期间为指示变量提供的值是遵循标准SQL语义来指示NULL值,还是可以使用扩展指示值,包括DEFAULT或UNASSIGNED。
带有扩展指示符的语句将被忽略,除非该语句是带有 VALUES 子句的 INSERT 语句、MERGE 语句或 UPDATE 语句。
- CONCENTRATE STATEMENTS OFF 或者 CONCENTRATE STATEMENTS WITH LITERALS
- 指定是否将包含文字常量的动态 SQL 语句作为单独的唯一名称条目缓存在动态语句缓存中,而不是与缓存中的现有语句共享。 如果新语句满足共享同一动态语句缓存版本的所有条件,则动态SQL语句可以共享缓存中的现有语句,但新语句指定了一个或多个与缓存语句不同的字面常量。
- CONCENTRATE STATEMENTS OFF
- 指定动态 SQL 语句中指定的文字常量,如果指定一个或多个与同一动态语句的缓存版本不同的常量,则该语句将被缓存为唯一语句条目。 CONCENTRATE STATEMENTS OFF 是默认的动态语句缓存行为。
- CONCENTRATE STATEMENTS WITH LITERALS
- 指定动态 SQL 语句中指定的文字常量将共享同一动态语句的缓存版本,如果新的动态语句满足共享缓存语句的所有条件,并且指定的常量可以代替缓存语句中的常量,则该动态语句也将使用 CONCENTRATE STATEMENTS WITH LITERALS 选项准备的动态语句,则该动态语句将共享缓存的动态语句,并且指定的常量可以代替缓存语句中的常量重复使用。
- FROM
- 指定语句字符串。 语句字符串是指定的字符串表达式或已识别的变量的值。
- 变量
必须根据字符串变量的声明规则,在应用程序中确定一个变量。 如果源字符串的长度超过 32KB ,则变量必须是CLOB或DBCLOB变量。 最大源字符串长度为 2MB ,但变量可以声明为大于 2MB。 指示变量不能与宿主变量一起指定。 在PL/I、COBOL和汇编语言中,主机变量必须是一个可变长度的字符串变量。 在C语言中,宿主变量不能是NUL字符串。 在SQL PL中,SQL变量用于代替主机变量,且其值不能为空。
- 字符串表达式
- 字符串表达式是指任何产生字符串的PL/I表达式。 字符串表达式不能以冒号开头。 字符串表达式中包含运算符或函数的变量不应以冒号开头。 当指定字符串表达式时,预编译器生成的字符串表达式结构使用 EBCDIC CCSID,并返回一条信息。
备注 PREPARE
- 语句字符串规则:
- 指定语句名称的值称为语句字符串。 语句字符串必须是下列其中一个 SQL 语句:
语句 语句 - ALLOCATE CURSOR
- ALTER
- ASSOCIATE LOCATORS
- COMMENT
- COMMIT
- 创建
- DECLARE GLOBAL TEMPORARY TABLE
- 删除
- DROP
- EXPLAIN
- FREE LOCATOR
- GRANT
- HOLD LOCATOR
- INSERT
- 标签
- LOCK TABLE
- MERGE
- REFRESH TABLE
- 发布 保存点 重命名
- REVOKE
- ROLLBACK
- SAVEPOINT
- select-statement
- SET 赋值语句
设置当前加速器
- 设置当前应用程序兼容性
- SET CURRENT DEGREE
- SET CURRENT DEBUG MODE
- SET CURRENT DECFLOAT ROUNDING MODE
- SET CURRENT EXPLAIN MODE
- SET CURRENT LOCALE LC_CTYPE
- SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION
- SET CURRENT OPTIMIZATION HINT
- SET CURRENT PRECISION
- SET CURRENT QUERY ACCELERATION
- SET CURRENT REFRESH AGE
- SET CURRENT ROUTINE VERSION
- SET CURRENT RULES
- SET CURRENT SQLID
- SET PATH
- SET SCHEMA
- SET CURRENT TEMPORAL BUSINESS_TIME
- SET CURRENT TEMPORAL SYSTEM_TIME
- 设置会话时区
- SIGNAL
TRANSFER OWNERSHIP
- TRUNCATE
- UPDATE
语句字符串不得具有以下属性:- 从执行SQL开始
- 以END-EXEC或分号结尾
包括对全局变量以外的变量的引用
包括对过渡变量的引用
- 参数标记:
- 虽然语句串不能包含对全局变量以外的变量的引用,但可以包含参数标记。 当执行准备好的语句时,参数标记会被变量值取代。 参数标记是一个问号(?),如果语句字符串是静态 SQL 语句,则变量可能出现在问号处。
有关参数标记如何被值替换的说明,请参阅 EXECUTE语句 、OPEN语句和动态执行数据更改语句。
参数标记分为两种类型:有类型和无类型:- 带类型参数标记 (typed parameter marker)
- 一个参数标记,指定了其目标数据类型。 键入的参数标记的一般形式为:
CAST(? AS data-type)
对CAST规范的调用意味着
,运行时参数的数据类型将是指定类型或可转换为指定类型的数据类型。 例如,在以下UPDATE语句中,TRANSLATE函数的参数值将在运行时提供:
为TRANSLATE函数提供的值的类型可以是VARCHAR(12),也可以是可转换为VARCHAR(12)的某种数据类型。 更多信息,请参阅 “分配与比较 ”。UPDATE EMPLOYEE SET LASTNAME = TRANSLATE(CAST(? AS VARCHAR(12))) WHERE EMPNO = ?
只要支持主机变量,且数据类型符合CAST规范中的约定,则动态SQL语句中可以使用类型化的参数标记。
- 隐式类型参数标记 (untyped parameter marker)
在未指定其目标数据类型的情况下指定的参数标记。 未定义的参数标记为单个问号。 参数标记出现的上下文决定了其数据类型。 例如,在上面的UPDATE语句中,谓词中无类型参数标记的数据类型与EMPNO列的数据类型相同。
未定义的参数标记可用于支持变量的动态 SQL 语句中的选定位置。 这些位置和由此产生的数据类型可在下表中找到。 表格将位置分为表达式、谓词、函数和其他语句,以帮助显示允许使用非类型参数标记的位置。 其他位置不支持未定义的参数标记。
- 表达式
未定义参数标记的位置 数据类型(不支持时显示错误) 独自入选。 例如: SELECT ?
错误 单个算术运算符的两个操作数,考虑了运算符优先级和运算规则。 包括以下情况: ? + ? + 10
DECFLOAT(34) 算术表达式中单个运算符的一个操作数(日期时间算术表达式除外)。 包括以下情况: ? + ? * 10
另一个操作数的数据类型 日期时间表达式的任何操作数。 例如: 'timecol + ?' or '? - datecol'
错误 在日期时间表达式中,带有标记的持续时间,其类型单位不是秒(标记的持续时间中指示单位类型的部分不能作为参数标记)。 小数点后15位 在日期时间表达式中,带有单位为秒的标注持续时间(标注持续时间中指示单位类型的部分不能作为参数标记)。 小数点后27位,12 CONCAT运算符的两个操作数 错误 当CONCAT运算符的另一个操作数是除CLOB以外的任何字符数据类型时,CONCAT运算符的一个操作数 如果另一个操作数是 CHAR(n) 或 VARCHAR(n ),且 n 小于 128,则数据类型为 VARCHAR(254 - n )。 在其他情况下,数据类型为VARCHAR(254)。 当CONCAT运算符的另一个操作数是除DBCLOB以外的任何图形数据类型时,CONCAT运算符的一个操作数 如果另一个操作数是 GRAPHIC(n) 或 VARGRAPHIC(n ),其中 n 小于 64,则数据类型为 VARGRAPHIC(127 - n )。 在其他情况下,数据类型为VARGRAPHIC(127)。 当CONCAT运算符的另一个操作数是除BLOB以外的任何二进制类型时,CONCAT运算符的一个操作数 如果另一个操作数是二进制(BINARY)或可变二进制(VARBINARY),且n小于128,则数据类型为可变二进制(VARBINARY)(255-n)。 在其他情况下,数据类型为VARBINARY(255) 当CONCAT运算符的另一个操作数是LOB字符串时,CONCAT运算符的一个操作数 另一个操作数(LOB字符串)的数据类型 在简单的 CASE 表达式中, CASE 关键字后面的表达式 错误 在简单 CASE 表达式中,当“WHEN”关键字后面出现任何或所有表达式时 将结果数据类型规则应用于 CASE 后面的表达式和WHEN后面的表达式(非无类型参数标记)的结果 当所有其他结果表达式为空或无类型参数标记时,任何 CASE 表达式中的结果表达式。 错误 当至少有一个其他结果表达式既不是 NULL 也不是无类型参数标记时,任何 CASE 表达式中的结果表达式。 将结果数据类型规则应用于所有非空或非类型参数标记的结果表达式 单独作为单行 VALUES 子句中的列表达式 ,且不在 INSERT 语句或 MERGE 语句插入操作的 VALUES 子句中 错误 在INSERT语句的单行VALUES子句中作为列表达式单独出现 列的数据类型,或者如果列被定义为不同类型,则为不同类型的源数据类型 在MERGE语句的源表中的 values-single-row 或 values-multiple-row 子句中作为列表达式单独出现 源表列的数据类型,或者如果数据类型是不同的类型,则为不同类型的源数据类型。 源表的列必须在MERGE语句的其他地方引用,以便根据其使用的上下文确定其数据类型,并且所有此类引用必须解析为相同的数据类型。 在MERGE语句插入操作的VALUES子句中作为列表达式单独出现 列的数据类型,或者如果列被定义为不同类型,则为不同类型的源数据类型 在MERGE语句的更新操作中,作为赋值语句右侧的列表达式单独存在 列的数据类型,或者如果列被定义为不同类型,则为不同类型的源数据类型 在UPDATE语句中,作为SET子句右侧的列表达式单独存在 列的数据类型,或者如果列被定义为不同类型,则为不同类型的源数据类型 在偏移条款中单独作为偏移行计数 BIGINT FETCH子句中单独作为 fetch-row-count BIGINT - 谓词
未定义参数标记的位置 数据类型(不支持时显示错误) 比较运算符的两个操作数 错误 当另一个操作数不是无类型参数标记时,比较运算符的一个操作数 另一个操作数的数据类型。 如果操作数具有日期时间数据类型,则DESCRIBE INPUT的结果将显示数据类型为CHAR(255),尽管 Db2 在任何比较中都使用日期时间数据类型。 BETWEEN谓词的所有操作数 错误 BETWEEN谓词的两个操作数(第一和第二或第一和第三) 非参数标记的操作数的数据类型 BETWEEN谓语只有一个操作数 将结果数据类型规则应用于非参数标记的其他操作数的结果 例如,IN谓词的所有操作数, ? IN (?,?,?)
错误 例如,IN谓词的第一个和第二个操作数, ? IN (?,A,B)
对IN列表中不是参数标记的操作数应用结果数据类型规则的结果 IN谓词的第一个操作数和IN列表中除第一个操作数之外的零个或多个操作数,例如, ? IN (A,?,B,?)
对IN列表中不是参数标记的操作数应用结果数据类型规则的结果 当右侧为全选全选时,IN谓词的第一个操作数,例如, ? IN (fullselect)
所选列的数据类型 IN 谓词的 IN 列表中的任何或全部操作数以及 IN 谓词的第一个操作数不是无类型参数标记,例如, A IN (?,A,?)
第一个操作数(IN列表左侧的操作数)的数据类型 LIKE谓词的所有操作数 第一个和第二个操作数 (匹配表达式和模式表达式 )是VARCHAR(4000)。 第三个操作数 (转义表达式 )是VARCHAR(1)。 当LIKE谓词的第一个操作数 (匹配表达式 )至少有一个其他操作数 (模式表达式或转义表达式 )不是无类型参数标记时。 VARCHAR(4000)、VARGRAPHIC(2000)或VARBINARY(4000),取决于第一个操作数的数据类型,该操作数不是无类型参数标记 当LIKE谓词的第二个操作数 (模式表达式 )中至少有一个操作数 (匹配表达式或转义表达式 )不是无类型参数标记时。 当LIKE子句中指定的模式是一个参数标记,并且使用固定长度的字符宿主变量来替换参数标记时,请为宿主变量指定一个正确长度的值。 如果您没有指定正确的长度,选择将不会返回预期的结果。 VARCHAR(4000)、VARGRAPHIC(2000)或VARBINARY(4000),取决于第一个操作数的数据类型,该操作数不是无类型参数标记。 当至少有一个其他操作数 (匹配表达式或模式表达式 )不是无类型参数标记时,LIKE谓词的第三个操作数 (转义表达式 ) CHAR(1)、GRAPHIC(1)或BINARY(1),取决于第一个操作数的数据类型,该操作数不是无类型参数标记 空谓词的运算数 错误 - 函数
未定义参数标记的位置 数据类型(不支持时显示错误) COALESCE或NULLIF的所有参数 错误 当至少有一个其他参数不是无类型参数标记时,COALESCE或NULLIF的任何参数 对非无类型参数标记的参数应用结果数据类型规则的结果 ,另一个参数的数据类型 COLLATION_KEY的第一个参数 VARGRAPHIC(2000) COLLATION_KEY的第二个参数 VARCHAR(255) LOWER的第一个参数 varchar(4000) LOWER的第二个参数 VARCHAR(255) 除MAX的第一个参数外的任何参数 函数实例中相应参数的数据类型 除MIN的第一个参数外的任何参数 函数实例中相应参数的数据类型 POSSTR或POSITION的两种说法 两个参数均为VARCHAR(4000) 当另一个参数为字符数据类型时,POSSTR或POSITION的一个参数 varchar(4000) 当另一个参数为图形数据类型时,POSSTR或POSITION的一个参数 VARGRAPHIC(2000) 当另一个参数是二进制或变长二进制数据类型时,POSSTR或POSITION参数的取值 VARBINARY(4000) 当另一个参数为BLOB时,POSSTR或POSITION的一个参数 BLOB(4000) SUBSTR或SUBSTRING的第一个参数 varchar(4000) SUBSTR或SUBSTRING的第二或第三个参数 INTEGER TIMESTAMP的一个论点 时间 TIMESTAMP_FORMAT的第一个参数 VARCHAR(255) TRANSLATE的第一个参数 错误 TRANSLATE的第二个或第三个参数 VARCHAR(4000)、VARGRAPHIC(2000),取决于第一个参数的数据类型是字符还是图形 TRANSLATE的第四个参数 VARCHAR(1)或VARGRAPHIC(1),取决于第一个参数的数据类型是字符还是图形 TRIM_ARRAY的第二个参数 BIGINT 数组索引用于数组元素说明 BIGINT UPPER的第一个参数 varchar(4000) UPPER的第二个参数 VARCHAR(255) VARCHAR_FORMAT的第一个参数 无时区时间戳 一元减 DECFLOAT(34) 一元加法 错误 任何内置标量函数的参数(本表所述者除外) 错误 内置聚合函数的参数 错误 用户定义标量函数、用户定义聚合函数或用户定义表函数的参数 函数实例中相应参数的数据类型 - 语句
未定义参数标记的位置 数据类型(不支持时显示错误) INSERT或MERGE语句的 FOR n ROWS 子句 整数 UPDATE语句中SET子句右侧的值或MERGE语句的UPDATE子句 源表列的数据类型,或者如果该列被定义为不同类型,则为不同类型的源数据类型。 源表的列必须在MERGE语句的其他地方引用,以便根据其使用的上下文确定其数据类型,并且所有此类引用必须解析为相同的数据类型。 价值、 value1 ,或 value2 在期限说明或期限条款中 在期间说明或期间条款中引用的期间列的数据类型 价值、 value1 ,或者 value2 在表的期间说明中,或在数据更改语句的期间子句中(如果语句的目标是表) 在期间说明或期间条款中引用的期间列的数据类型 价值、 value1 ,或者 value2 在视图的周期说明中 错误 value1 或 value2 在数据更改语句中的期间子句中,如果语句的目标是视图 错误
- 使用敏感静态光标时FETCH语句的注意事项:
- 光标外部的更改是否对光标可见取决于与敏感静态光标一起使用的FETCH类型:
- 敏感的FETCH对光标所做的所有更新和删除(包括触发器所做的更改)以及所有其他应用程序进程所做的已提交更新和删除都很敏感,因为每个提取的行都是从基础表而不是临时表中检索的。 这是敏感游标的默认FETCH语句类型。
使用光标对基础数据进行更改后,该行将自动刷新。 使用这种光标进行的更改可能会导致光标结果表中产生孔洞。 此外,重新获取行(获取已经获取的行)可能会导致结果表中存在空行。 如果敏感的FETCH被用来重新获取一行数据,而该行不再符合查询条件,就会导致“删除漏洞”或“更新漏洞”。 在这种情况下,不会返回任何数据,光标停留在孔上。
- INSENSITIVE FETCH对光标外的更新和删除不敏感,但对光标内的更新和删除敏感。 在结果表中用敏感FETCH语句更新行内容之前,用触发器进行的更改在非敏感FETCH中不可见。 如果应用程序不想对光标之外的变化敏感(即应用程序不想看到其他光标或其他应用程序进程所做的更改),则可以将“不敏感”明确指定为 SENSITIVE STATIC 光标的 FETCH 语句的一部分。 这种类型的FETCH可用于刷新用户数据缓冲区中的数据。 更多信息,请参阅 INSENSITIVE。
- 敏感的FETCH对光标所做的所有更新和删除(包括触发器所做的更改)以及所有其他应用程序进程所做的已提交更新和删除都很敏感,因为每个提取的行都是从基础表而不是临时表中检索的。 这是敏感游标的默认FETCH语句类型。
- 错误检查:
- 执行 PREPARE 语句时,会解析语句字符串并检查是否存在错误。 如果语句字符串无效,则不会创建预编译语句,并在SQLCA中报告阻止创建的错误条件。
在本地和远程处理中,DEFER(PREPARE)和REOPT(ALWAYS)/REOPT(ONCE)绑定选项可能会导致某些SQL语句出现
延迟
错误。 例如,描述、执行和打开可能会收到通常在准备处理期间出现的 SQLCODE。 - 参考和执行规则:
- 准备好的发言稿可在以下几种发言稿中引用,但须遵守以下限制:
语句类型 限制准备好的发言 DESCRIBE 无限制 DECLARE CURSOR 当光标打开时,语句必须是 SELECT EXECUTE 语句不能为 SELECT 准备的语句可以执行多次。 实际上,如果已准备的语句不多次执行并且不包含参数标记,那么使用 EXECUTE IMMEDIATE 语句(而不是 PREPARE 和 EXECUTE 语句)会更有效。
- 准备好的声明持久性:
- 当工作单元终止时,该单元创建的所有准备好的语句都会被销毁,但以下情况除外:
- 如果执行提交操作时游标处于打开状态,则使用选项 WITH HOLD 声明游标的 SELECT 语句在提交操作执行期间保持打开状态。
如果您的系统启用了动态语句缓存,则绑定 KEEPDYNAMIC(YES) 的 SELECT、INSERT、UPDATE、MERGE 和 DELETE 语句将在提交或回滚点之后保留,且以下条件均不成立:
- 网站已发布SQL版本
- 使用了断开(自动)选项
- 使用了绑定选项“断开(条件)”,并且该网站没有保留光标
- 与释放(解除分配)选项绑定或使用该选项并引用已声明的全局临时表的插入、更新、合并和删除语句在提交操作后仍会保留,除非以下语句之一为真:
- 已声明的全局临时表使用ON COMMIT DROP TABLE选项定义。
- 该语句还引用了 Db2 基本对象(例如表或视图),且以下语句之一为真:
- 基本对象引用用于 Db2 目录表。
- 在提交点, Db2 确定另一个 Db2 线程正在等待基础对象数据库描述符(DBD)上的X-lock。
- 该语句引用了XML函数或操作,在提交点 Db2 确定必须释放XML操作的基础对象DBD S-lock。
- 在提交点, Db2 确定语句使用的基对象DBD S-lock必须释放,且不能在提交点之间保持。
- Db2 确定另一个 线程正在等待包含该语句的 包的X-lock。 Db2 Db2
- 声明范围 姓名:
- 语句名称的作用域与游标名称的作用域相同。 有关游标名称的作用域的更多信息,请参见 DECLARE CURSOR语句。
- 使用PREPARE INTO和REOPT绑定选项进行准备:
- 如果绑定选项 REOPT(ALWAYS) 或 REOPT(ONCE) 生效,则 PREPARE INTO 相当于执行 PREPARE 和 DESCRIBE。 如果语句有输入变量,则DESCRIBE命令会使用默认值来准备语句,当打开或执行语句时,必须再次准备语句。 当REOPT(ONCE)生效时,即使没有输入变量,语句也会被准备两次。 因此,为避免重复准备语句,当REOPT(ALWAYS)或REOPT(ONCE)生效时,请避免使用PREPARE INTO。
- PREPARE语句和SELECT或DECLARE CURSOR语句中光标属性的关系:
- 选择语句中指定的光标属性将代替PREPARE语句中ATTRIBUTES子句指定的任何相应选项。 PREPARE语句的ATTRIBUTES子句中指定的属性优先于DECLARE CURSOR语句中指定的任何相应选项。 光标属性的使用顺序如下:
- 选择(最高优先级)
- PREPARE语句ATTRIBUTES子句
- 声明游标(最低优先级)
例如,假设宿主变量 MYQ 已设置为以下 SELECT 语句:SELECT WORKDEPT, EMPNO, SALARY, BONUS, COMM FROM EMP WHERE WORKDEPT IN ('D11', 'D21') FOR UPDATE OF SALARY, BONUS, COMM
如果发出以下PREPARE语句,则将使用SELECT语句中指定的FOR UPDATE子句,而不是PREPARE语句中与ATTRIBUTES子句一起指定的FOR READ ONLY子句。 因此,光标可以更新。attrstring = 'FOR READ ONLY'; EXEC SQL PREPARE stmt1 ATTRIBUTES :attrstring FROM :MYQ;
- 当前解释模式特殊寄存器的效果:
- 如果将当前解释模式特殊寄存器设置为解释,则该语句仅用于解释,不可执行,除非该语句是SET语句。 尝试执行准备好的语句将返回错误。 更多信息请参见当前解释模式特殊寄存器。
- SELECT和UPDATE WHERE CURRENT OF定位更新的属性优先级:
- 如果UPDATE WHERE CURRENT OF语句和相关的SELECT语句都已准备就绪,且两个语句具有相同的PREPARE属性,则UPDATE WHERE CURRENT OF语句的PREPARE属性值将覆盖SELECT语句的PREPARE属性值。
- 扩展指示器PREPARE属性对动态执行的定位更新的影响:
- 如果同时准备带有WHERE CURRENT OF子句的UPDATE语句和相关的SELECT语句,则是否使用扩展指示变量取决于每个PREPARE语句中的WITH EXTENDED INDICATORS或WITHOUT EXTENDED INDICATORS属性。
SELECT和UPDATE语句的PREPARE语句扩展指示器属性之间的交互
SELECT语句中PREPARE的扩展指示器属性 带有WHERE CURRENT OF子句的PREPARE for UPDATE语句的扩展指示器属性 结果 带扩展指示器 带扩展指示器 UPDATE语句的PREPARE属性优先于SELECT语句的PREPARE属性。 不可更新的列可以出现在选择列表中。 带扩展指示器 无扩展指示器 UPDATE语句在执行时没有扩展的指示器参数。 带扩展指示器 默认(未指定属性) SELECT语句的PREPARE属性会覆盖UPDATE语句的默认PREPARE属性。 不可更新的列可以出现在选择列表中。 无扩展指示器 带扩展指示器 UPDATE语句的PREPARE属性优先于SELECT语句的PREPARE属性。 不可更新的列不在隐式或显式选择列表中。 无扩展指示器 无扩展指示器 UPDATE语句在执行时没有扩展的指示器参数。 无扩展指示器 默认(未指定属性) SELECT语句的PREPARE属性会覆盖UPDATE语句的默认PREPARE属性。 UPDATE语句在执行时没有扩展的指示器参数。 默认(未指定属性) 带扩展指示器 UPDATE语句的PREPARE属性优先于SELECT语句的PREPARE属性。 不可更新的列不在隐式或显式选择列表中。 默认(未指定属性) 无扩展指示器 UPDATE语句的PREPARE属性优先于SELECT语句的PREPARE属性。 UPDATE语句在执行时没有扩展的指示器参数。 默认(未指定属性) 默认(未指定属性) UPDATE语句在执行时没有扩展的指示器参数。 - SKIPUNCI子系统参数与PREPARE语句之间的交互:
- 当PREPARE语句指定了CURRENTLY COMMITTED或WAIT FOR OUTCOME子句,并且子系统参数SKIPUNCI生效时,下表描述了未提交的插入是否被跳过,或者事务是否将等待提交或回滚完成:
SKIPUNCI子系统参数与PREPARE语句之间的交互
SKIPUNCI
子系统参数的值准备陈述 属性 正在工作 跳过未提交的插入,
,或等待提交
或回滚是 当前已落实 跳过 是 等待结果 等待 是 未指定 跳过 否 当前已落实 跳过 否 等待结果 等待 否 未指定 等待 - 扩展指示变量和延迟错误检查:
- 启用扩展指示变量后,未分配指示器的指示器值会导致语句中省略关联的目标列。 因此,通常在语句准备阶段进行的验证(识别对不可更新列的插入或更新)被推迟到语句执行阶段。 如果语句验证失败,则在运行语句时返回错误,而不是在准备语句时。
- 在动态语句缓存中重复使用已准备好的语句,并 CONCENTRATE STATEMENTS WITH LITERALS
- 为了能够重复使用常量,新语句和缓存语句中的常量必须具有以下相同点:
- 直接使用环境
- 数据类型
- 数据类型长度和大小
如果 Db2 确定两个常量都满足重用标准,则可以使用 CONCENTRATE STATEMENTS WITH LITERALS 选项准备的缓存语句可以由同一个SQL语句与不同的常量共享。 尽管新的动态 SQL 语句将共享缓存的语句,但新语句在运行时将使用自己的文字常量,而不是缓存语句的常量。
但也有一些例外。 例如,内置函数SUBSTR,由于使用环境直接,在缓存语句中不断重复使用不同的常量值,可能会导致输出或结果不正确。 在这种情况下,只有与语句缓存版本具有完全相同常量值的SQL语句实例才适合重复使用。 Db2 确定这种即时使用上下文限制何时何地适用。
当 CONCENTRATE STATEMENTS WITH LITERALS 选项时, Db2 仅考虑与REOPT(ONCE)或REOPT(AUTO)绑定选项绑定的语句的访问路径选择常量值。
DECFLOAT定义的常量NAN、SNAN和INFINITY可用于字面常量的重复使用。
以下示例展示了PREPARE如何与 CONCENTRATE STATEMENTS WITH LITERALS。 X、Y和Z是定义为十进制数据类型的列:DECLARE C1 CURSOR FOR DYNSQL_WITH_LITERAL; DYNSQL_SELECT = ‘SELECT X, Y, Z FROM TABLE1 WHERE X < 9'; attrstring = ‘CONCENTRATE STATEMENTS WITH LITERALS'; EXEC SQL PREPARE DYNSQL_WITH_LITERAL ATTRIBUTES :attrstring FROM :DYNSQL_SELECT; EXEC SQL OPEN C1;
DYNSQL_INSERT = ‘INSERT INTO TABLE1 (X, Y, Z) VALUES (8,109,29)'; attrstring = ‘CONCENTRATE STATEMENTS WITH LITERALS'; EXEC SQL PREPARE DYNSQL_INSERT_WITH_LITERAL ATTRIBUTES :attrstring FROM :DYNSQL_INSERT; EXEC SQL EXECUTE DYNSQL_INSERT_WITH_LITERAL;
例子 PREPARE
- 示例 1
- 在这个PL/I示例中,准备并执行了带有参数标记的INSERT语句。 在执行之前,参数标记的值被读入主机变量 S1、 S2、 S3、 S4 和 S5。
EXEC SQL PREPARE DEPT_INSERT FROM 'INSERT INTO DSN8C10.DEPT VALUES(?,?,?,?,?)'; -- Check for successful execution and read values into host variables EXEC SQL EXECUTE DEPT_INSERT USING :S1, :S2, :S3, :S4, :S5;
- 示例 2
- 准备一个动态SELECT语句,在PREPARE语句中使用一个主机变量来指定游标的属性。 假设SELECT语句的文本位于名为stmttxt的变量中,游标的属性位于名为attrvar的变量中。
EXEC SQL DECLARE mycursor CURSOR FOR mystmt; EXEC SQL PREPARE mystmt ATTRIBUTES :attrvar FROM :stmttxt; EXEC SQL DESCRIBE mystmt INTO :mysqlda; EXEC SQL OPEN mycursor; EXEC SQL FETCH FROM mycursor USING DESCRIPTOR :mysqlda;