get

EGL get 语句检索单个文件记录或数据库行,并提供了一个选项以允许稍后在代码中替换或删除所存储的数据。另外,此语句允许检索一组数据库行并将每个后续行放到动态数组中的下一个 SQL 记录中。

get 语句有时被标识为 get by key value,它与以 get 开头的其它语句是不同的。


get 语句的语法图
record name
I/O 对象的名称:带索引记录、相对记录或 SQL 记录。对于 SQL 处理,如果未指定 EGL INTO 子句(稍后描述),则记录名是必需的。
forUpdate
一个选项,它允许以后使用 EGL 语句来替换或删除从文件或数据库中检索到的数据。

如果资源是可恢复的(如对于 VSAM 文件或 SQL 数据库的情况),则 forUpdate 选项锁定记录,以使它在提交发生之前不能被其它程序更改。有关提交处理的详细信息,请参阅逻辑工作单元

resultSetID
结果集标识,用于 EGL replacedeleteexecute 语句以及 EGL close 语句。有关详细信息,请参阅 resultSetID
singleRow
一个选项,它导致生成更有效率的 SQL,当您确定 get 语句中的搜索条件只适用于一行并且不打算更新或删除该行时,此选项适用。如果在搜索条件适用于多行时指定此选项,则会导致运行时 I/O 错误。有关其它详细信息,请参阅 SQL 记录
#sql{ sqlStatement }
显式的 SQL SELECT 语句,如 SQL 支持中所述。不要在 #sql 与左花括号之间留下任何空格。
into ... item
EGL INTO 子句,它标识从关系数据库中接收值的 EGL 主变量。在下列任何一种情况下,当处理 SQL 时,此子句是必需的:
  • 未指定 SQL 记录;或者
  • 同时指定了 SQL 记录和显式 SQL SELECT 语句,但 SQL SELECT 子句中的列与记录项无关。(关联位于 SQL 记录部件中,如 SQL 项属性中所述。)

在与此子句类似的子句中(该子句位于 #sql{ } 块外部),不要在主变量名称之前包括分号。

preparedStatementID
在运行时准备 SQL SELECT 语句的 EGL prepare 语句的标识。get 语句动态地运行 SQL SELECT 语句。有关详细信息,请参阅 prepare
using ... item
USING 子句,它标识在运行时可供已准备的 SQL SELECT 语句使用的 EGL 主变量。在类似于此子句的子句(该子句位于 sqlend 块的外部)中,不要在主变量名称之前包括分号。
usingKeys ... item
标识用来构建隐式 SQL 语句中的 WHERE 子句的键值部分的键项列表。如果未指定显式 SQL 语句,则在运行时将使用隐式 SQL 语句。

如果未指定 usingKeys 子句,则隐式语句的键值部分基于 get 语句所引用的 SQL 记录部件,或者基于作为 get 语句所引用的动态数组基础的 SQL 记录部件。

对于动态数组,usingKeys 子句中的项(或者是 SQL 记录中的主变量)一定不能位于作为动态数组基础的 SQL 记录中。

如果指定显式 SQL 语句,则将忽略 usingKeys 信息。

SQL dynamic array
由 SQL 记录组成的动态数组的名称。
以下示例显示如何读取和替换文件记录:
  emp.empnum = 1;         // sets the key in record emp

  try
    get emp forUpdate;
  onException
    myErrorHandler(8);  // exits the program
  end
    
  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end
    
当检索数据库行时,下一个 get 语句将使用 SQL 记录 emp,并且不可能进行后续更新或删除:
  try
    get emp singleRow into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };
  onException
    myErrorHandler(8);
  end
    
下一个示例使用同一个 SQL 记录来替换 SQL 行:
  try
    get emp forUpdate into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };

  onException
    myErrorHandler(8);  // exits the program
  end
    
  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end
    

有关 get 语句的详细信息取决于记录类型。有关 SQL 处理的详细信息,请参阅 SQL 记录

带索引记录

当对带索引记录发出 get 语句时,记录中的键值确定从文件中检索哪个记录。

如果要替换或删除带索引记录(或相对记录),则必须对该记录发出 get 语句,然后发出文件更改语句(replacedelete),在此之间不对同一个文件执行任何 I/O 操作。在发出 get 语句之后,对同一文件执行的下一个 I/O 操作的效果如下所示:
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 replace 语句,则在文件中更改该记录
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 delete 语句,则在文件中对该记录设置删除标记
  • 如果下一个 I/O 操作是对同一文件中的记录执行的 get 语句,并包含 forUpdate 选项,则后续 replacedelete 语句对新读取的文件记录有效
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 get 语句(不带 forUpdate 选项)或者是对同一个文件执行的 close 语句,则释放文件记录而不进行更改

如果文件是 VSAM 文件,则 EGL get 语句(带有 forUpdate 选项)将防止记录被其它程序更改。

相对记录

当对相对记录发出 get 语句时,与记录相关联的键项确定从文件中检索哪个记录。该键项必须可供任何使用该记录的函数使用,并且可以是下列任何一项:
  • 同一记录中的项
  • 记录中对于程序来说是全局的项,或者对于运行 get 语句的函数来说是局部的项
  • 对于程序来说是全局的数据项,或者对于运行 get 语句的函数来说是局部的数据项
如果要替换或删除带索引记录(或相对记录),则必须对该记录发出 get 语句,然后发出文件更改语句(replacedelete),在此之间不对同一个文件执行任何 I/O 操作。在发出 get 语句之后,对同一文件执行的下一个 I/O 操作的效果如下所示:
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 replace 语句,则在文件中更改该记录
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 delete 语句,则在文件中对该记录设置删除标记
  • 如果下一个 I/O 操作是对同一文件执行的 get(带有 forUpdate 选项),则后续 replace 或 delete 对新读取的文件记录有效
  • 如果下一个 I/O 操作是对同一个 EGL 记录执行的 get(不带 forUpdate 选项)或者是对同一个文件执行的 close,则释放文件记录而不进行更改

SQL 记录

EGL get 语句导致生成的代码包含 SQL SELECT 语句。如果指定 singleRow 选项,则 SQL SELECT 语句是独立语句。另外,SQL SELECT 语句是游标中的子句,如 SQL 支持中所述。

错误状态

当使用 get 语句来从关系数据库中读取数据时,无效的情况包括:
  • 指定了不是 SELECT 类型的 SQL 语句
  • 直接在 SQL SELECT 语句中指定 SQL INTO 子句
  • 除 SQL INTO 子句之外,指定了 SELECT 语句的一部分但非全部子句
  • 指定(或接受)的 SQL SELECT 语句与不存在的列相关联,或者和相关主变量不兼容
下列错误状态都是使用 forUpdate 选项时可能发生的错误状态:
  • 指定(或接受)的 SQL 语句意图更新多表;或者
  • 使用了 SQL 记录作为 I/O 对象,并且所有记录项都是只读的。
并且,下列情况将导致错误:
  • 定制了带有 forUpdate 选项的 EGL get 语句,但未指示特定 SQL 表列可用于更新;并且
  • 与该 get 语句相关的 replace 语句尝试修改该列。
可以通过下列任何一种方法来解决前述不匹配问题:
  • 定制 EGL get 语句时,在 SQL SELECT 语句的 FOR UPDATE OF 子句中包括列名;或者
  • 在定制 EGL replace 语句时,消除对 SQL UPDATE 语句的 SET 子句中的列的引用;或
  • getreplace 语句接受缺省值。

隐式 SQL SELECT 语句

当指定 SQL 记录来作为 get 语句的 I/O 对象,但未指定显式 SQL 语句时,隐式 SQL SELECT 具有下列特征:

  • 只要每个 SQL 表键列中的值等于 SQL 记录的相应键项中的值,名为 defaultSelectCondition 的特定于记录的属性就确定所选择的表行。如果既没有指定记录键也没有指定缺省选择条件,则选择所有表行。如果由于任何原因而选择了多个表行,则将检索到的第一行放在记录中。
  • 作为记录项与记录定义中的 SQL 表列相关联的结果,给定的项接收相关 SQL 表列的内容。
  • 如果指定 forUpdate 选项,则 SQL SELECT FOR UPDATE 语句不包括只读记录项。
  • 除了仅当 get 语句包含 forUpdate 选项时才存在 FOR UPDATE OF 子句以外,特定记录的 SQL SELECT 语句与以下语句类似:
      SELECT column01,
             column02, ...
             columnNN
      FROM   tableName
      WHERE  keyColumn01 = :keyItem01
      FOR UPDATE OF
             column01,
             column02, ...
             columnNN
    独立 SQL SELECT 上的 SQL INTO 子句或者与游标相关的 FETCH 语句上的 SQL INTO 子句与以下子句相似:
      INTO   :recordItem01,
             :recordItem02, ...
             :recordItemNN

    当未指定 INTO 子句时,如果将 SQL 记录与显式 SQL SELECT 语句配合使用,则 EGL 派生 SQL INTO 子句。派生的 INTO 子句中的项就是与 SQL 语句的 SELECT 子句中列示的列相关联的那些项。(项与列的关联位于 SQL 记录部件中,如 SQL 项属性中所述。)如果列未与项相关联,则 EGL INTO 子句是必需的。

当指定 SQL 记录动态数组来作为 get 语句的 I/O 对象,但未指定显式 SQL 语句时,隐式 SQL SELECT 类似于对单个 SQL 记录描述的 SQL SELECT,但有下列区别:
  • 查询的键值部分是基于大于等于条件的关系集合:
      keyColumn01 >= :keyItem01 &
      keyColumn02 >= :keyItem02 &
             .
             .
             .
      keyColumnN  >= :keyItemN
  • usingKeys 子句中的项(或者是 SQL 记录中的主变量)一定不能位于作为动态数组基础的 SQL 记录中。

相关任务
语法图

使用条款 | 反馈
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.