Ims Db 简明教程
IMS DB - Overview
A Brief Overview
数据库是关联数据项的集合。这些数据项以提供快速且轻松访问的方式进行组织和存储。IMS 数据库是分层数据库,数据存储在不同级别,每个实体都依赖于更高级别的实体。使用 IMS 的应用程序系统上的物理元素如下图所示。
Database Management
数据库管理系统是一组应用程序,用于存储、访问和管理数据库中的数据。IMS 数据库管理系统通过以易于检索的方式组织数据来维护完整性,并允许快速恢复数据。IMS 通过其数据库管理系统的帮助维护大量世界公司数据。
Transaction Manager
事务管理器的功能是提供数据库和应用程序之间的通信平台。IMS 充当事务管理器。事务管理器与最终用户打交道,以从数据库存储和检索数据。IMS 可以使用 IMS DB 或 DB2 作为后端数据库来存储数据。
DL/I – Data Language Interface
DL/I 包含允许访问存储在数据库中的数据的应用程序。IMS DB 使用 DL/I,DL/I 作为程序员在应用程序中访问数据库时使用的接口语言。我们将在接下来的章节中更详细地讨论这一点。
IMS DB - Structure
Hierarchical Structure
IMS 数据库是容纳物理文件的数据集合。在分层数据库中,最顶层包含有关实体的一般信息。随着我们在层次结构中从顶层往下移动,我们会获得更多有关实体的信息。
层次结构中的每一层都包含段。在标准文件中,难以实现层次结构,但 DL/I 支持层次结构。下图描绘了 IMS DB 的结构。
Segment
重点注意事项:
-
通过将相似数据分组在一起来创建段。
-
它是 DL/I 在任何输入输出操作中传输到应用程序和从应用程序传输的最小信息单元。
-
一个段可以有一个或多个分组在一起的数据字段。
在以下示例中,段 Student 有四个数据字段。
Student |
Roll Number |
Name |
Course |
Mobile NUmber |
IMS DB - DL/I Terminology
层次数据库在两个或更多段之间建立关联。以下示例演示了各个段在 IMS 数据库结构中的关联方式。
Root Segment
重点注意事项:
-
位于层次结构顶部的段称为根段。
-
根段是访问所有从属段的唯一段。
-
根段是数据库中唯一一个永远不会成为子段的段。
-
IMS 数据库结构中只能有一个根段。
-
例如,在上述示例中 'A' 是根段。
Dependent Segment
重点注意事项:
-
除根段外的所有段都称为从属段。
-
从属段依赖于一个或多个段来呈现完整含义。
-
例如,在我们的示例中 'B', 'C1', 'C2', 'D', 'E', 'F1' 和 'F2' 是从属段。
Child Segment
重点注意事项:
-
任何在层次结构中直接高于其的段的段都称为子段。
-
结构中的每个从属段都是一个子段。
-
For example, 'B', 'C1', 'C2', 'D', 'E', 'F1' and 'F2' are child segments.
IMS DB - DL/I Processing
IMS DB 在不同级别存储数据。通过从应用程序发出 DL/I 调用来检索和插入数据。我们将在即将到来的章节中详细讨论 DL/I 调用。可以用以下两种方式处理数据:
-
Sequential Processing
-
Random Processing
Sequential Processing
当从数据库中按顺序检索段时,DL/I 遵循一个预定义模式。让我们了解一下 IMS DB 的顺序处理。
以下是有关顺序处理的要点:
-
用于访问 DL/I 中数据的预定义模式是先向下遍历层级,然后从左到右。
-
先检索根段,然后 DL/I 移动到第一个左子级并一直向下到最低层级。在最低层级,它检索所有孪生段的出现情况。然后它移动到右侧段。
-
为了更好地理解,观察上方图中的箭头,它们显示了访问段的流程。图书馆是根段,流程从那里开始,一直到汽车来访问单个记录。同样的流程重复发生于所有出现情况,以获取所有数据记录。
-
在访问数据时,程序利用数据库中的 position 来帮助检索和插入段。
IMS DB - Control Blocks
IMS 控制块定义 IMS 数据库的结构和程序对它们的访问权限。下图显示了 IMS 控制块的结构。
DL/I 使用以下三种类型的控制块 −
-
Database Descriptor (DBD)
-
Program Specification Block (PSB)
-
Access Control Block (ACB)
Database Descriptor (DBD)
重点注意事项:
-
DBD 一旦定义了所有段,就描述了数据库的完整物理结构。
-
在安装 DL/I 数据库时,必须创建 DBD,因为需要访问 IMS 数据库。
-
应用程序可以使用 DBD 的不同视图。它们称为应用程序数据结构,它们在程序规范块中指定。
-
数据库管理员通过编码 DBDGEN 控制语句来创建 DBD。
DBDGEN
DBDGEN 是数据库描述符生成器。创建控制块是数据库管理员的责任。所有负载模块都存储在 IMS 库中。汇编语言宏语句用于创建控制块。下面提供了一个示例代码,演示如何使用 DBDGEN 控制语句创建 DBD −
PRINT NOGEN
DBD NAME=LIBRARY,ACCESS=HIDAM
DATASET DD1=LIB,DEVICE=3380
SEGM NAME=LIBSEG,PARENT=0,BYTES=10
FIELD NAME=(LIBRARY,SEQ,U),BYTES=10,START=1,TYPE=C
SEGM NAME=BOOKSEG,PARENT=LIBSEG,BYTES=5
FIELD NAME=(BOOKS,SEQ,U),BYTES=10,START=1,TYPE=C
SEGM NAME=MAGSEG,PARENT=LIBSEG,BYTES=9
FIELD NAME=(MAGZINES,SEQ),BYTES=8,START=1,TYPE=C
DBDGEN
FINISH
END
让我们了解上述 DBDGEN 中使用的术语 −
-
当您在 JCL 中执行上述控制语句时,它创建一个物理结构,其中 LIBRARY 是根段,而 BOOKS 和 MAGZINES 是其子段。
-
第一个 DBD 宏语句标识数据库。在此,我们需要提及 DL/I 用于访问此数据库的 NAME 和 ACCESS。
-
第二个 DATASET 宏语句标识包含数据库的文件。
-
使用 SEGM 宏语句定义段类型。我们需要指定该段的 PARENT。如果它是根段,则提及 PARENT=0。
下表显示了 FIELD 宏语句中使用的参数 −
S.No |
Parameter & Description |
1 |
Name 字段名称,通常为 1 到 8 个字符长 |
2 |
Bytes Length of the field |
3 |
Start 段内字段的位置 |
4 |
Type 字段的数据类型 |
5 |
Type C Character data type |
6 |
Type P 打包十进制数据类型 |
7 |
Type Z 带区十进制数据类型 |
8 |
Type X Hexadecimal data type |
9 |
Type H 半字二进制数据类型 |
10 |
Type F 整字二进制数据类型 |
Program Specification Block (PSB)
PSB 的基础知识如下所述 −
-
数据库有一个由 DBD 定义的单一物理结构,但处理它的应用程序可以有不同的数据库视图。这些视图称为应用程序数据结构,并且在 PSB 中定义。
-
没有哪个程序可以在单次执行中使用多个 PSB。
-
应用程序有自己的 PSB,对于具有相似数据库处理要求的应用程序共享 PSB 来说是常见的。
-
PSB 由一个或多个称为程序通信块 (PCB) 的控制块组成。PSB 为应用程序程序将访问的每个 DL/I 数据库包含一个 PCB。我们将在后续模块中详细讨论 PCB。
-
必须执行 PSBGEN 才能为程序创建 PSB。
PSBGEN
PSBGEN 被称为程序规范块生成器。以下示例使用 PSBGEN 创建 PSB −
PRINT NOGEN
PCB TYPE=DB,DBDNAME=LIBRARY,KEYLEN=10,PROCOPT=LS
SENSEG NAME=LIBSEG
SENSEG NAME=BOOKSEG,PARENT=LIBSEG
SENSEG NAME=MAGSEG,PARENT=LIBSEG
PSBGEN PSBNAME=LIBPSB,LANG=COBOL
END
让我们了解上述 DBDGEN 中使用的术语 −
-
The first macro statement is the Program Communication Block (PCB) that describes the database Type, Name, Key-Length, and Processing Option.
-
DBDNAME parameter on the PCB macro specifies the name of the DBD. KEYLEN specifies the length of the longest concatenated key. The program can process in the database. PROCOPT parameter specifies the program’s processing options. For example, LS means only LOAD Operations.
-
SENSEG is known as Segment Level Sensitivity. It defines the program’s access to parts of the database and it is identified at the segment level. The program has access to all the fields within the segments to which it is sensitive. A program can also have field-level sensitivity. In this, we define a segment name and the parent name of the segment.
-
The last macro statement is PCBGEN. PSBGEN is the last statement telling there are no more statements to process. PSBNAME defines the name given to the output PSB module. The LANG parameter specifies the language in which the application program is written, e.g., COBOL.
Access Control Block (ACB)
Listed below are the points to note about access control blocks −
-
Access Control Blocks for an application program combines the Database Descriptor and the Program Specification Block into an executable form.
-
ACBGEN is known as Access Control Blocks Generator. It is used to generate ACBs.
-
For online programs, we need to pre-build ACBs. Hence the ACBGEN utility is executed before executing the application program.
-
For batch programs, ACBs can be generated at execution time too.
IMS DB - Programming
包含 DL/I 调用的应用程序不能直接执行。相反,需要一个 JCL 来触发 IMS DL/I 批处理模块。IMS 中的批处理初始化模块是 DFSRRC00。应用程序和 DL/I 模块一起执行。下图显示了包含 DL/I 调用以访问数据库的应用程序的结构。
应用程序通过以下程序元素与 IMS DL/I 模块进行接口 −
-
ENTRY 语句指定该程序利用 PCB。
-
PCB 掩码与预先构建的 PCB 中保留的信息相关,从 IMS 接收返回值信息。
-
输入输出区用于向 IMS 数据库传递数据段并从该数据库接收数据段。
-
对 DL/I 的调用指定诸如获取、插入、删除、替换等处理函数。
-
检查状态代码用于检查指定的处理选项的 SQL 返回代码,以了解操作是否成功。
-
Terminate 语句用于结束包含 DL/I 的应用程序的处理。
Segments Layout
到目前为止,我们了解到 IMS 由在高级编程语言中用于访问数据的段组成。考虑一下我们之前见过的图书馆的以下 IMS 数据库结构,这里我们将在 COBOL 中看到其段的布局 −
01 LIBRARY-SEGMENT.
05 BOOK-ID PIC X(5).
05 ISSUE-DATE PIC X(10).
05 RETURN-DATE PIC X(10).
05 STUDENT-ID PIC A(25).
01 BOOK-SEGMENT.
05 BOOK-ID PIC X(5).
05 BOOK-NAME PIC A(30).
05 AUTHOR PIC A(25).
01 STUDENT-SEGMENT.
05 STUDENT-ID PIC X(5).
05 STUDENT-NAME PIC A(25).
05 DIVISION PIC X(10).
IMS DB - Cobol Basics
We include DL/I calls inside COBOL application program to communicate with IMS database. We use the following DL/I statements in COBOL program to access the database −
-
Entry Statement
-
Goback Statement
-
Call Statement
Entry Statement
It is used to pass the control from the DL/I to the COBOL program. Here is the syntax of the entry statement −
ENTRY 'DLITCBL' USING pcb-name1
[pcb-name2]
上述语句是在 COBOL 程序的 Procedure Division 中编码的。让我们详细了解一下 COBOL 程序中的 Entry 语句——
-
批量初始化模块触发应用程序并在其控制下执行。
-
DL/I 加载所需的控制块和模块以及应用程序程序,并将控制权交给应用程序。
-
DLITCBL 代表 DL/I to COBOL 。Entry 语句用于定义程序中的入口点。
-
当我们在 COBOL 中调用一个子程序时,也会提供其地址。同样,当 DL/I 将控制权交给应用程序时,它也会提供程序的 PSB 中定义的每个 PCB 的地址。
-
应用程序程序中使用的所有 PCB 必须在 COBOL 程序的 Linkage Section 内定义,因为 PCB 驻留在应用程序程序之外。
-
链接节内的 PCB 定义称为 PCB Mask 。
-
PCB 掩码和存储中的实际 PCB 之间的关系是通过在 Entry 语句中列出 PCB 来创建的。Entry 语句中的列出顺序应与它们在 PSBGEN 中出现的顺序相同。
Goback Statement
用于将控制传递回 IMS 控制程序。以下是 Goback 语句的语法 −
GOBACK
以下是关于 Goback 语句的基本注意事项 −
-
GOBACK 在应用程序的末尾编码。它将控制从程序返回到 DL/I。
-
我们不应该使用 STOP RUN 因为它将控制返回给操作系统。如果我们使用 STOP RUN,则 DL/I 永远没有机会执行其终止功能。这就是为什么在 DL/I 应用程序中使用 Goback 语句。
-
在发出 Goback 语句之前,必须关闭 COBOL 应用程序中使用的所有非 DL/I 数据集,否则程序将异常终止。
Call Statement
Call 语句用于请求 DL/I 服务,例如对 IMS 数据库执行某些操作。以下是 call 语句的语法 −
CALL 'CBLTDLI' USING DLI Function Code
PCB Mask
Segment I/O Area
[Segment Search Arguments]
上面的语法显示了您可以与 call 语句一起使用的参数。我们将在下表中讨论每一个参数 −
S.No. |
Parameter & Description |
1 |
DLI Function Code 标识要执行的 DL/I 函数。此参数是描述 I/O 操作的四个字符字段的名称。 |
2 |
PCB Mask 联编段内 PCB 定义称为 PCB 掩码。它们在 entry 语句中使用。不需要 SELECT、ASSIGN、OPEN 或 CLOSE 语句。 |
3 |
Segment I/O Area 输入/输出工作区的名称。这是应用程序程序的区域,DL/I 将请求的段放入其中。 |
4 |
Segment Search Arguments 这些是可选参数,具体取决于发出的 call 的类型。它们用于搜索 IMS 数据库中的数据段。 |
以下是关于 Call 语句的注意事项 −
-
CBLTDLI 表示 COBOL to DL/I 。它是与程序 object module 一起链接编辑的接口 module 的名称。
-
在每次 DL/I 调用之后,DLI 会将状态代码存储在 PCB 中。程序可以使用此代码确定调用是否成功或失败。
Example
有关 COBOL 的更多信息,您可以参阅我们的 COBOL 教程 here 。以下示例显示了使用 IMS 数据库和 DL/I 调用的 COBOL 程序的结构。我们将在接下来的章节中详细讨论示例中使用的每个参数。
IDENTIFICATION DIVISION.
PROGRAM-ID. TEST1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 DLI-FUNCTIONS.
05 DLI-GU PIC X(4) VALUE 'GU '.
05 DLI-GHU PIC X(4) VALUE 'GHU '.
05 DLI-GN PIC X(4) VALUE 'GN '.
05 DLI-GHN PIC X(4) VALUE 'GHN '.
05 DLI-GNP PIC X(4) VALUE 'GNP '.
05 DLI-GHNP PIC X(4) VALUE 'GHNP'.
05 DLI-ISRT PIC X(4) VALUE 'ISRT'.
05 DLI-DLET PIC X(4) VALUE 'DLET'.
05 DLI-REPL PIC X(4) VALUE 'REPL'.
05 DLI-CHKP PIC X(4) VALUE 'CHKP'.
05 DLI-XRST PIC X(4) VALUE 'XRST'.
05 DLI-PCB PIC X(4) VALUE 'PCB '.
01 SEGMENT-I-O-AREA PIC X(150).
LINKAGE SECTION.
01 STUDENT-PCB-MASK.
05 STD-DBD-NAME PIC X(8).
05 STD-SEGMENT-LEVEL PIC XX.
05 STD-STATUS-CODE PIC XX.
05 STD-PROC-OPTIONS PIC X(4).
05 FILLER PIC S9(5) COMP.
05 STD-SEGMENT-NAME PIC X(8).
05 STD-KEY-LENGTH PIC S9(5) COMP.
05 STD-NUMB-SENS-SEGS PIC S9(5) COMP.
05 STD-KEY PIC X(11).
PROCEDURE DIVISION.
ENTRY 'DLITCBL' USING STUDENT-PCB-MASK.
A000-READ-PARA.
110-GET-INVENTORY-SEGMENT.
CALL ‘CBLTDLI’ USING DLI-GN
STUDENT-PCB-MASK
SEGMENT-I-O-AREA.
GOBACK.
IMS DB - DL/I Functions
DL/I 函数是 DL/I 调用中使用的第一个参数。此函数指示 IMS DL/I 调用将在 IMS 数据库上执行哪个操作。DL/I 函数的语法如下 -
01 DLI-FUNCTIONS.
05 DLI-GU PIC X(4) VALUE 'GU '.
05 DLI-GHU PIC X(4) VALUE 'GHU '.
05 DLI-GN PIC X(4) VALUE 'GN '.
05 DLI-GHN PIC X(4) VALUE 'GHN '.
05 DLI-GNP PIC X(4) VALUE 'GNP '.
05 DLI-GHNP PIC X(4) VALUE 'GHNP'.
05 DLI-ISRT PIC X(4) VALUE 'ISRT'.
05 DLI-DLET PIC X(4) VALUE 'DLET'.
05 DLI-REPL PIC X(4) VALUE 'REPL'.
05 DLI-CHKP PIC X(4) VALUE 'CHKP'.
05 DLI-XRST PIC X(4) VALUE 'XRST'.
05 DLI-PCB PIC X(4) VALUE 'PCB '.
此语法表示以下要点 -
-
对于此参数,我们可以提供任何四个字符的名称作为存储字段以存储函数代码。
-
DL/I 功能参数在 COBOL 程序的工作存储部分中编码。
-
为了指定 DL/I 功能,程序员需要在 DL/I 调用中编码一个 05 级数据名称,如 DLI-GU,因为 COBOL 并不允许在 CALL 语句中编码常量。
-
DL/I 功能分为三类:获取、更新和其他功能。让我们详细讨论每一类。
Get Functions
获取功能类似于任何编程语言所支持的读取操作。获取功能用于从 IMS DL/I 数据库提取段。以下获取功能用于 IMS DB 中 −
-
Get Unique
-
Get Next
-
Get Next within Parent
-
Get Hold Unique
-
Get Hold Next
-
在父级内获取保持下一个
让我们考虑以下 IMS 数据库结构以了解 DL/I 函数调用 −
Get Unique
“GU”代码用于唯一获取功能。它类似于 COBOL 中的随机读取语句。它用于基于字段值获取特定段出现。可以使用段搜索参数提供字段值。GU 调用的语法如下 −
CALL 'CBLTDLI' USING DLI-GU
PCB Mask
Segment I/O Area
[Segment Search Arguments]
如果你通过在 COBOL 程序中为所有参数提供适当的值来执行上述调用语句,你便可以在数据库中的段 I/O 区域中检索该段。在上述示例中,如果你提供图书馆、杂志和健康这三个字段值,那么你便可以获取健康段的所需出现。
Get Next
“GN”代码用于获取下一个功能。它类似于 COBOL 中的读取下一个语句。它用于按顺序获取段出现。访问数据段出现的预定义模式是从层次结构往下,然后从左到右。GN 调用的语法如下 −
CALL 'CBLTDLI' USING DLI-GN
PCB Mask
Segment I/O Area
[Segment Search Arguments]
如果你通过在 COBOL 程序中为所有参数提供适当的值来执行上述调用语句,你便可以在数据库中按顺序在段 I/O 区域中检索段出现。在上述示例中,它首先访问图书馆段,然后访问书籍段,以此类推。我们又一次又一次地执行 GN 调用,直到达到我们想要的段出现。
Get Next within Parent
“GNP”代码用于在父级内获取下一个。该函数用于按顺序检索建立父级段的从属段出现。GNP 调用的语法如下 −
CALL 'CBLTDLI' USING DLI-GNP
PCB Mask
Segment I/O Area
[Segment Search Arguments]
Get Hold Unique
“GHU”代码用于唯一保持获取。保持功能指定我们在检索后将更新该段。唯一保持获取功能对应于唯一获取调用。以下是 GHU 调用的语法 −
CALL 'CBLTDLI' USING DLI-GHU
PCB Mask
Segment I/O Area
[Segment Search Arguments]
Update Functions
更新函数类似于其他任何编程语言中的重写或插入操作。更新函数用于更新 IMS DL/I 数据库中的段。在使用更新功能之前,必须使用保持子句成功调用段出现。以下更新函数用于 IMS DB −
-
Insert
-
Delete
-
Replace
Insert
“ISRT”代码用于插入功能。ISRT 函数用于向数据库添加一个新段。它用于更改现有数据库或加载新数据库。以下是 ISRT 调用的语法 −
CALL 'CBLTDLI' USING DLI-ISRT
PCB Mask
Segment I/O Area
[Segment Search Arguments]
Other Functions
以下其他函数用于 IMS DL/I 调用 −
-
Checkpoint
-
Restart
-
PCB
Checkpoint
“CHKP”代码用于检查点功能。它用于IMS的恢复功能。下面给出CHKP调用的语法 −
CALL 'CBLTDLI' USING DLI-CHKP
PCB Mask
Segment I/O Area
[Segment Search Arguments]
IMS DB - PCB Mask
PCB 的全称为 Program Communication Block(程序通信块)。PCB Mask 是在 DL/I 调用中使用的第二个参数。在链接部分中声明。以下是 PCB Mask 的语法:
01 PCB-NAME.
05 DBD-NAME PIC X(8).
05 SEG-LEVEL PIC XX.
05 STATUS-CODE PIC XX.
05 PROC-OPTIONS PIC X(4).
05 RESERVED-DLI PIC S9(5).
05 SEG-NAME PIC X(8).
05 LENGTH-FB-KEY PIC S9(5).
05 NUMB-SENS-SEGS PIC S9(5).
05 KEY-FB-AREA PIC X(n).
以下为重点注意事项:
-
对于每个数据库,DL/I 维护一个被称为程序通信块的存储区域。它存储有关在应用程序中访问的数据库的信息。
-
ENTRY 语句在链接部分和程序 PSB 内的 PCB Mask 之间创建连接。DL/I 调用中使用的 PCB Mask 告知要为操作使用哪个数据库。
-
您可以假设这类似于在 COBOL READ 语句中指定文件名或在 COBOL 写入语句中指定记录名。不需要 SELECT、ASSIGN、OPEN 或 CLOSE 语句。
-
在每次 DL/I 调用之后,DL/I 在 PCB 中存储状态代码,程序可使用该代码确定调用是否成功或失败。
Segment Level
重点注意事项:
-
段级别被称为段层次级级别指示器。它包含字符数据,长度为两个字节。
-
段级别字段存储处理段的级别。检索到段后,会存储检索到的段的级别。
-
段级别字段的值不超过 15,因为这是 DL/I 数据库中允许的最大级别数。
IMS DB - SSA
SSA 表示段搜索参数。SSA 用于标识被访问的段发生。它是一个可选参数。我们可以根据要求包含任意数量的 SSA。SSA 有两种类型 −
-
Unqualified SSA
-
Qualified SSA
Unqualified SSA
不合格 SSA 提供了在调用中所使用段的名称。下面给出了不合格 SSA 的语法 −
01 UNQUALIFIED-SSA.
05 SEGMENT-NAME PIC X(8).
05 FILLER PIC X VALUE SPACE.
不合格 SSA 的要点如下 −
-
基本的不合格 SSA 为 9 字节长。
-
前 8 个字节保存用于处理的段名称。
-
最后一个字节总是包含空格。
-
DL/I uses the last byte to determine the type of SSA.
-
To access a particular segment, move the name of the segment in the SEGMENT-NAME field.
The following images show the structures of unqualified and qualified SSAs −
Qualified SSA
A Qualified SSA provides the segment type with the specific database occurrence of a segment. Given below is the syntax of a Qualified SSA −
01 QUALIFIED-SSA.
05 SEGMENT-NAME PIC X(8).
05 FILLER PIC X(01) VALUE '('.
05 FIELD-NAME PIC X(8).
05 REL-OPR PIC X(2).
05 SEARCH-VALUE PIC X(n).
05 FILLER PIC X(n+1) VALUE ')'.
合格的SSA的主要内容如下−
-
合格的SSA的前8个字节包含用于处理的段名。
-
第九个字节是一个左括号“(”。
-
从第十位开始的接下来的8字节指定我们想要搜索的字段名称。
-
在字段名称之后,在第18和19位中,我们指定两位字符的关系运算符代码。
-
然后我们在括号中指定字段值,最后一个字节右括号)”。
下表显示了合格的SSA中使用的关系运算符。
Relational Operator |
Symbol |
Description |
EQ |
= |
Equal |
NE |
~= ˜ |
Not equal |
GT |
> |
Greater than |
GE |
>= |
Greater than or equal |
LT |
<< |
Less than |
LE |
⇐ |
Less than or equal |
Command Codes
命令代码用于增强DL/I调用的功能。命令代码减少了DL/I调用的数量,使程序变得简单。此外,它提高了性能,这是因为减少了调用的数量。下图显示了在不合格和合格的SSA中如何使用命令代码−
命令代码的主要要点如下−
-
要使用命令代码,请在SSA的第9个位置指定星号,如上图所示。
-
命令代码编码在第十位。
-
从第10位开始,DL/I认为所有字符都是命令代码,直到它遇到一个不合格的SSA空格或一个合格的SSA左括号。
下表显示了SSA中使用的命令代码列表−
Command Code |
Description |
C |
Concatenated Key |
D |
Path Call |
F |
First Occurrence |
L |
Last Occurrence |
N |
Path Call Ignore |
P |
Set Parentage |
Q |
Enqueue Segment |
U |
Maintain Position at this level |
V |
Maintain Position at this and all above levels |
- |
Null Command Code |
Multiple Qualifications
多重限定的基本要点如下 −
-
当我们需要对两个或更多限定符或字段进行比较时,需要多重限定。
-
我们使用布尔运算符,如 AND 和 OR 来连接两个或更多限定。
-
当我们想要基于单个字段的可能值的范围来处理一段时,可以使用多重限定。
以下是多重限定的语法 −
01 QUALIFIED-SSA.
05 SEGMENT-NAME PIC X(8).
05 FILLER PIC X(01) VALUE '('.
05 FIELD-NAME1 PIC X(8).
05 REL-OPR PIC X(2).
05 SEARCH-VALUE1 PIC X(m).
05 MUL-QUAL PIC X VALUE '&'.
05 FIELD-NAME2 PIC X(8).
05 REL-OPR PIC X(2).
05 SEARCH-VALUE2 PIC X(n).
05 FILLER PIC X(n+1) VALUE ')'.
MUL-QUAL 是 MULtiple QUALIification 的简称,其中我们可以提供布尔运算符,如 AND 或 OR。
IMS DB - Data Retrieval
IMS DL/I 调用中使用的各种数据检索方法如下 −
-
GU Call
-
GN Call
-
Using Command Codes
-
Multiple Processing
让我们考虑以下 IMS 数据库结构,以了解数据检索函数调用 −
GU Call
GU 调用的基本原理如下 −
-
GU 调用称为 Get Unique 调用。它用于随机处理。
-
如果应用程序没有定期更新数据库,或者数据库更新数量较少,那么可以使用随机处理。
-
GU 调用用于将指针置于某个特定位置,以便后续顺序检索。
-
GU 调用独立于由前一个调用建立的指针位置。
-
GU 调用处理基于调用语句中所提供的唯一键字段。
-
如果我们提供了非唯一的键字段,那么 DL/I 将返回该键字段的第一个分段出现。
CALL 'CBLTDLI' USING DLI-GU
PCB-NAME
IO-AREA
LIBRARY-SSA
BOOKS-SSA
ENGINEERING-SSA
IT-SSA
上面的示例显示,我们通过提供一组完整的限定 SSA 来发出 GU 调用。它包括了从根级别到我们要检索的分段出现的全部键字段。
GN Call
GN调用的基本原理如下:
-
GN 调用称为“获取下一个”调用。它用于基本的顺序处理。
-
数据库中指针的初始位置在第一个数据库记录的根分段之前。
-
在成功的 GN 调用之后,数据库指针位置在序列中的下一个分段出现之前。
-
GN 调用根据先前的调用所建立的位置开始遍历数据库。
-
如果 GN 调用是非限定的,那么它将返回数据库中下一个分段出现,而不论其类型,按照层次结构顺序。
-
如果 GN 调用包括 SSA,那么 DL/I 仅检索满足所有指定 SSA 要求的分段。
CALL 'CBLTDLI' USING DLI-GN
PCB-NAME
IO-AREA
BOOKS-SSA
上面的示例显示我们发出一个 GN 调用,提供开始读取记录的顺序位置。它获取 BOOKS 段的第一个出现。
Command Codes
命令码与调用一起用于获取段出现。下面将讨论与调用一起使用的各种命令码。
F Command Code
重点注意事项:
-
当在调用中指定 F 命令码时,该调用处理段的第一个出现。
-
当我们想要顺序处理时,可以使用 F 命令码,它可与 GN 调用和 GNP 调用一起使用。
-
如果我们使用 GU 调用指定 F 命令码,则它没有任何意义,因为 GU 调用默认获取第一个段出现。
D Command Code
重点注意事项:
-
D 命令码用于仅使用单个调用获取多个段出现。
-
通常,DL/I 对 SSA 中指定的最低级别段进行操作,但在很多情况下,我们也需要其他级别的段数据。在这些情况下,我们可以使用 D 命令码。
-
D 命令码使得可以轻松检索段的整个路径。
C Command Code
重点注意事项:
-
C 命令码用于连接键。
-
使用关系运算符有点复杂,因为我们需要指定一个字段名称、一个关系运算符和一个搜索值。相反,我们可以使用 C 命令码提供连接的键。
以下示例演示了 C 命令码的使用 −
01 LOCATION-SSA.
05 FILLER PIC X(11) VALUE ‘INLOCSEG*C(‘.
05 LIBRARY-SSA PIC X(5).
05 BOOKS-SSA PIC X(4).
05 ENGINEERING-SSA PIC X(6).
05 IT-SSA PIC X(3)
05 FILLER PIC X VALUE ‘)’.
CALL 'CBLTDLI' USING DLI-GU
PCB-NAME
IO-AREA
LOCATION-SSA
P Command Code
重点注意事项:
-
当我们发出 GU 或 GN 调用时,DL/I 会在检索到的最低级别段处建立其父系关系。
-
如果我们包括 P 命令代码,那么 DL/I 将在分层路径的高级别段上建立其父级关系。
IMS DB - Data Manipulation
IMS DL/I 调用中使用的不同数据操作方法如下:
-
ISRT Call
-
Get Hold Calls
-
REPL Call
-
DLET Call
让我们考虑以下 IMS 数据库结构以了解数据操作函数调用:
ISRT Call
重点注意事项:
-
ISRT 调用称为插入调用,用于向数据库添加段出现。
-
ISRT 调用用于加载新数据库。
-
当段描述字段已加载数据时,我们发出 ISRT 调用。
-
必须在调用中指定未限定或限定 SSA,以便 DL/I 知道在何处放置段出现。
-
我们在调用中可以使用未限定和限定 SSA 的组合。所有上述级别都可以指定限定 SSA。让我们考虑以下示例:
CALL 'CBLTDLI' USING DLI-ISRT
PCB-NAME
IO-AREA
LIBRARY-SSA
BOOKS-SSA
UNQUALIFIED-ENGINEERING-SSA
上面的示例表明我们正通过提供限定和未限定 SSA 的组合来发出 ISRT 调用。
当我们正在插入的新段具有唯一键字段时,它将被添加到适当的位置。如果键字段不是唯一的,那么将按照数据库管理员定义的规则添加它。
当我们发出一个 ISRT 调用而没有指定关键字段时,插入规则会告诉我们如何将段相对于现有的孪生段放置。下面给出插入规则——
-
First − 如果规则是 first(第一个),则新段将被添加到任何现有的孪生段之前。
-
Last − 如果规则是 last(最后一个),则新段将被添加到所有现有的孪生段之后。
-
Here − 如果规则是 here(这里),则它将相对于现有的孪生段添加到当前位置,可能是第一个、最后一个或任何位置。
Status Codes
下表显示了 ISRT 调用后的相关状态代码——
S.No |
Status Code & Description |
1 |
Spaces Successful call |
2 |
GE Multiple SSAs are used and the DL/I cannot satisfy the call with the specified path. |
3 |
II Try to add a segment occurrence that is already present in the database. |
4 |
LB / LC LD / LE We get these status codes while load processing. In most cases, they indicate that you are not inserting the segments in an exact hierarchical sequence. |
Get Hold Call
重点注意事项:
-
There are three types of Get Hold call which we specify in a DL/I call: Get Hold Unique (GHU) Get Hold Next (GHN) Get Hold Next within Parent (GHNP)
-
Hold function specifies that we are going to update the segment after retrieval. So before an REPL or DLET call, a successful hold call must be issued telling the DL/I an intent to update the database.
REPL Call
重点注意事项:
-
After a successful get hold call, we issue an REPL call to update a segment occurrence.
-
We cannot change the length of a segment using an REPL call.
-
We cannot change the value of a key field using an REPL call.
-
We cannot use a qualified SSA with an REPL call. If we specify a qualified SSA, then the call fails.
CALL 'CBLTDLI' USING DLI-GHU
PCB-NAME
IO-AREA
LIBRARY-SSA
BOOKS-SSA
ENGINEERING-SSA
IT-SSA.
*Move the values which you want to update in IT segment occurrence*
CALL ‘CBLTDLI’ USING DLI-REPL
PCB-NAME
IO-AREA.
The above example updates the IT segment occurrence using an REPL call. First, we issue a GHU call to get the segment occurrence we want to update. Then, we issue an REPL call to update the values of that segment.
DLET Call
重点注意事项:
-
DLET call works much in the same way as an REPL call does.
-
After a successful get hold call, we issue a DLET call to delete a segment occurrence.
-
We cannot use a qualified SSA with a DLET call. If we specify a qualified SSA, then the call fails.
CALL 'CBLTDLI' USING DLI-GHU
PCB-NAME
IO-AREA
LIBRARY-SSA
BOOKS-SSA
ENGINEERING-SSA
IT-SSA.
CALL ‘CBLTDLI’ USING DLI-DLET
PCB-NAME
IO-AREA.
The above example deletes the IT segment occurrence using a DLET call. First, we issue a GHU call to get the segment occurrence we want to delete. Then, we issue a DLET call to update the values of that segment.
IMS DB - Secondary Indexing
当我们想访问数据库而不使用完整的串联键,或者当我们不想使用顺序主键字段时,将使用辅助索引。
Index Pointer Segment
DL/I 在单独的数据库中存储指向索引数据库段的指针。索引指针段是辅助索引中唯一一种类型。它由以下两个部分组成 -
-
Prefix Element
.
-
Data Element
Secondary Keys
重点注意事项:
-
建立辅助索引的索引源段中的字段被称为辅助键。
-
任何字段均可用作辅助键。它不必是段顺序字段。
-
辅助键可以是索引源段内单个字段的任何组合。
-
辅助键值不一定是唯一的。
Secondary Data Structures
重点注意事项:
-
当我们构建辅助索引时,数据库的明显层次结构也会改变。
-
索引目标段变为明显的根段。如下图所示,即使工程段不是根段,它也变为根段。
-
由辅助索引造成的数据库结构的重排被称为辅助数据结构。
-
辅助数据结构不会对磁盘上存在的数据库主物理结构做出任何更改。它只是一种在应用程序之前改变数据库结构的方法。
Independent AND Operator
重点注意事项:
-
在辅助索引中使用 AND (* 或 &) 运算符时,它称为受控 AND 运算符。
-
独立的 AND (#) 允许我们指定依赖 AND 不可能完成的限定条件。
-
该运算符只能用于索引源段依赖于索引目标段的辅助索引。
-
可以使用 SSA 编码独立 AND 来指定,根据两个或多个依赖源段中的字段来处理目标段的发生。
01 ITEM-SELECTION-SSA.
05 FILLER PIC X(8).
05 FILLER PIC X(1) VALUE '('.
05 FILLER PIC X(10).
05 SSA-KEY-1 PIC X(8).
05 FILLER PIC X VALUE '#'.
05 FILLER PIC X(10).
05 SSA-KEY-2 PIC X(8).
05 FILLER PIC X VALUE ')'.
Sparse Sequencing
重点注意事项:
-
稀疏排序也称为稀疏索引。我们可以使用稀疏排序从索引中删除一些索引源段,使用辅助索引数据库。
-
稀疏排序用于提高性能。当不使用索引源段的一些发生时,我们可以将其删除。
-
DL/I 使用抑制值、抑制例程或两者来确定是否应对段进行索引。
-
如果索引源段中顺序字段的值与抑制值相匹配,则不会建立索引关系。
-
抑制例程是评估段并确定是否应为其编制索引的用户编写的程序。
-
当使用稀疏索引时,它的函数由 DL/I 处理。我们不需要在应用程序中为它做出特殊规定。
IMS DB - Logical Database
IMS数据库有一条规则,即每个段类型只能有一个父段。这就限制了物理数据库的复杂性。许多DL/I应用程序需要一个复杂结构,它允许一个段具有两个父段类型。为了克服这一限制,DL/I允许DBA实现逻辑关系,其中一个段可以具有物理父段和逻辑父段。我们可以在一个物理数据库中创建其他关系。实现逻辑关系之后的新数据结构称为逻辑数据库。
Logical Relationship
逻辑关系具有以下属性 −
-
逻辑关系是两个在逻辑上(而非物理上)相关的段之间的路径。
-
通常,在单独的数据库之间建立逻辑关系。但一个特定数据库的段之间也是有可能建立关系的。
下图显示了两个不同的数据库。一个是学生数据库,另一个是图书数据库。我们在学生数据库中的“已借阅书籍”段和图书数据库中的“书籍”段之间创建逻辑关系。
创建逻辑关系后,逻辑数据库如下所示 −
Logical Child Segment
逻辑子段是逻辑关系的基础。它是一个物理数据段,但对于DL/I来说,它看起来好像有两个父段。上面示例中的“书籍”段有两个父段。“已借阅书籍”段是逻辑父段,而“图书”段是物理父段。一个逻辑子段实例只有一个逻辑父段实例,并且一个逻辑父段实例可以具有许多逻辑子段实例。
Types of Logical Relationships
DBA在段之间创建逻辑关系。为了实现逻辑关系,DBA必须在所涉及的物理数据库的DBDGEN中指定它。有三种类型的逻辑关系 −
-
Unidirectional
-
Bidirectional Virtual
-
Bidirectional Physical
Programming Considerations
使用逻辑数据库的编程注意事项如下 −
-
访问数据库的DL/I调用在逻辑数据库中仍然相同。
-
程序规范块指示我们在调用中使用的结构。在某些情况下,我们无法识别我们正在使用一个逻辑数据库。
-
逻辑关系为数据库编程增加了新维度。
-
使用逻辑数据库时必须谨慎,因为两个数据库被集成在一起了。如果修改一个数据库,同样的修改必须反应在另一个数据库中。
-
程序规范应该指明什么处理被允许用在一个数据库上。如果违反了处理规则,你就会得到一个非空白状态码。
Concatenated Segment
一个逻辑子段总是以目标父级的完整串联键开头。这被称为目标父级串联键 (DPCK)。对于逻辑子级的段 I/O 区域,你始终需要在开头编码 DPCK。在一个逻辑数据库中,串联段使得在不同物理数据库中定义的段之间形成连接。一个串联段包括以下两部分:
-
Logical child segment
-
Destination parent segment
一个逻辑子级段包括以下两部分:
-
目标父级串联键 (DPCK)
-
Logical child user data
在更新期间处理串联段时,有可能通过一个调用添加或修改逻辑子级和目标父级中的数据。这还取决于 DBA 为数据库指定的规则。对于一个插入,将 DPCK 放置在正确的位置。对于一个替换或删除,不要更改串联段的任何部分中的 DPCK 或序列字段数据。
IMS DB - Recovery
数据库管理员需要针对系统故障制定数据库恢复计划。故障可能有多种类型,例如应用程序崩溃、硬件错误、电源故障等。
Simple Approach
一些简单的数据库恢复方法如下 −
-
定期对重要数据集制作备份副本,以便保留针对该数据集发布的所有事务。
-
如果某个数据集因系统故障而损坏,可以通过还原备份副本来更正该问题。然后,将累积的事务重新发布到备份副本以使其是最新的。
Abnormal Termination Routines
DL/I 程序的崩溃方式与标准程序的崩溃方式不同,因为标准程序是由操作系统直接执行的,而 DL/I 程序则不是。通过使用异常终止例程,系统会进行干预,以便在异常终止 (ABEND) 后可以进行恢复。异常终止例程执行以下操作 −
-
Closes all datasets
-
取消队列中所有待处理作业
-
创建存储转储以找出 ABEND 的根本原因
该例程的局限性在于,它无法确保正在使用的数据是否准确。
DL/I Log
当应用程序 ABEND 时,有必要还原应用程序所做的更改、更正错误并重新运行应用程序。为此,必须拥有 DL/I 日志。以下是有关 DL/I 日志记录的关键点 −
-
DL/I 在文件中记录应用程序所做的所有更改,该文件称为日志文件。
-
当应用程序更改一个段时,DL/I 会创建它的之前映像和之后映像。
-
如果应用程序崩溃,可以使用这些段映像来还原这些段。
-
DL/I 使用一种称为“预写日志记录”的技术来记录数据库更改。通过预先写日志记录,数据库更改在写入实际数据集之前先写入日志数据集。
-
由于日志始终领先于数据库,恢复实用程序可以确定任何数据库更改的状态。
-
当程序执行调用以更改数据库段时,DL/I 将负责其日志记录部分。
Recovery – Forward and Backward
数据库恢复的两种方法是 -
-
Forward Recovery - DL/I 使用日志文件存储更改数据。积累的交易使用此日志文件重新过帐。
-
Backward Recovery -向后恢复也称为回退恢复。程序的日志记录被反向读取,它们的影响在数据库中被逆转。当回退完成时,数据库处于与故障发生前相同的状态,假设在此期间没有其他应用程序程序更改数据库。
Checkpoint
检查点是应用程序程序执行的数据库更改被认为是完整且准确的阶段。下面列出了有关检查点需要注意的事项 -
-
最近的检查点之前进行的数据库更改不会被向后恢复逆转。
-
在正向恢复期间,最近检查点之后记录的数据库更改不会应用于数据库的映像副本。
-
使用检查点方法,当恢复过程完成时,数据库将恢复到其在最近检查点时的状态。
-
批处理程序的默认设置是检查点是程序的开始。
-
可以使用检查点调用 (CHKP) 建立检查点。
-
检查点调用会触发检查点记录被写入 DL/I 日志。
以下是 CHKP 调用的语法 -
CALL 'CBLTDLI' USING DLI-CHKP
PCB-NAME
CHECKPOINT-ID
有两种检查点方法 -
-
Basic Checkpointing - 它允许程序员发出 DL/I 恢复实用程序在恢复处理期间使用的检查点调用。
-
Symbolic Checkpointing - 这是检查点的先进形式,与扩展重启功能结合使用。符号检查点和扩展重启共同让应用程序程序员编写程序,以便它们可以在检查点之后的点继续处理。