第012章以簇方式存 储数据对象.docx
《第012章以簇方式存 储数据对象.docx》由会员分享,可在线阅读,更多相关《第012章以簇方式存 储数据对象.docx(19页珍藏版)》请在冰点文库上搜索。
![第012章以簇方式存 储数据对象.docx](https://file1.bingdoc.com/fileroot1/2023-6/9/46831ff4-5d9e-42d9-9306-db85920cfb2e/46831ff4-5d9e-42d9-9306-db85920cfb2e1.gif)
第012章以簇方式存储数据对象
第十二章1以簇方式存储数据对象
概览
内容
ABAP/4内存中的数据簇
在ABAP/4内存中存储数据对象
从内存中读取数据对象
删除内存中的数据簇
数据库中的数据簇
簇数据库
在簇数据库中存储数据对象
创建数据簇目录表
从簇数据库中读取数据对象
从簇数据库中删除数据簇
用开放式SQL语句访问簇数据库
可以用数据簇方式对ABAP/4程序的任何复杂内部数据对象进行分组保存,并将其临时存储在ABAP/4内存中,或长时间存储在数据库中。
在下列主题中,您将学到更多有关在内存和数据库中存储数据簇的知识
1ABAP/4内存中的数据簇
可以在ABAP/4内存中存储数据簇。
ABAP/4内存是分配给特定事务的存储区,任何模块都是用关键词CALL或SUBMIT从中进行调用的。
关于事务流的详细信息,参见编写ABAP/4事务(页Error!
Notavalidlink.)。
ABAP/4内存与在事务期间生成该内存的ABAP/4程序或程序模块无关。
这意味着在同一事务中,存储在ABAP/4内存中的对象可由任何ABAP/4程序重新读取。
但本节所说的ABAP/4内存与不受事务限制的全局SAP内存不同(对于示例,参见将SPA/GPA参数传送到事务(页Error!
Notavalidlink.))。
ABAP/4内存允许跨越多个程序层次,在不同模块化单元之间进行数据传递。
例如,可以在下列单元之间传递数据:
_报表和其他SUBMIT调用的报表
_事务和报表
_不同对话模块
_程序和功能模块
等等。
离开事务后,就释放该内存。
使用EXPORTTOMEMORY语句在内存中存储数据对象。
使用IMPORTFROMMEMORY语句从内存中读取数据对象。
使用FREEMEMORY语句从内存中删除数据簇。
2在ABAP/4内存中存储数据对象
要将数据对象从ABAP/4程序写入ABAP/4内存,请使用下列语句:
语法
EXPORT[FROM][FROM]...TOMEMORYID.
此语句将列表中指定的数据对象存储为ABAP/4内存中的数据簇。
如果忽略选项FROM,则将数据对象存储到自己的名称之下。
如果使用该选项,则将数据对象存储到下面。
ID用于标识内存数据,不得超过32个字符。
EXPORT语句总是完全改写ID相同的任何现有数据簇的内容。
对于有表头行的内表,只可以存储表本身,而不能存储表头行。
在EXPORT语句中,将表名解释为表。
这是例外。
通常情况下,语句将表名解释为表工作区(参见访问内表(页8–4))。
PROGRAMSAPMZTS1.
DATATEXT1(10)VALUE'Exporting'.
DATAITABLIKESBOOKOCCURS10WITHHEADERLINE.
DO5TIMES.
ITAB-BOOKID=100+SY-INDEX.
APPENDITAB.
ENDDO.
EXPORTTEXT1
TEXT2FROM'Literal'
TOMEMORYID'text'.
EXPORTITAB
TOMEMORYID'table'.
在此示例中,文本字段TEXT1和TEXT2存储到程序SAPMZTS1的ABAP/4内存的ID“文本”之下,内表ITAB则存储到ID“表”中。
2从内存中读取数据对象
要将ABAP/4内存中的数据对象读到ABAP/4程序中,请使用下列语句:
语法
IMPORT[TO][TO]...FROMMEMORYID.
此语句从ABAP/4内存的数据簇中读取列表中指定的数据对象。
如果忽略选项TO,则将内存中的数据对象赋给程序中的同名数据对象。
如果使用此选项,则将内存中的数据对象写入字段中。
ID用于标识内存数据,不得超过32个字符。
不必读取存储在特定ID下的所有对象。
相反,可以从名称中进行选择。
如果内存中不包含指定ID下的对象,则将SY-SUBRC设置为4。
但是,如果内存中存在带此ID的数据簇,无论数据对象是否也存在,SY-SUBRC之值总是为0。
如果簇中不存在数据对象,则目标字段保持不变。
此语句不进行这种检查:
即内存中的对象结构与要写入的结构是否匹配。
因为数据是按位进行传送的,所以不匹配的结构可能会引起不一致。
PROGRAMSAPMZTS1.
DATATEXT1(10)VALUE'Exporting'.
DATAITABLIKESBOOKOCCURS10WITHHEADERLINE.
DO5TIMES.
ITAB-BOOKID=100+SY-INDEX.
APPENDITAB.
ENDDO.
EXPORTTEXT1
TEXT2FROM'Literal'
TOMEMORYID'text'.
EXPORTITAB
TOMEMORYID'table'.
SUBMITSAPMZTS2ANDRETURN.
SUBMITSAPMZTS3.
程序的第一部分对应于在ABAP/4内存中存储数据对象(页2)中的示例。
当前示例也以SUBMIT调用程序SAPMZTS1和SAPMZTS2。
通过在ABAP/4编辑器中双击程序名生成和维护SUBMIT后面指定的程序。
关于SUBMIT的详细信息,参见调用报表(页Error!
Notavalidlink.)。
SAPMZTS2的示例:
PROGRAMSAPMZTS2.
DATA:
TEXT1(10),
TEXT3LIKETEXT1VALUE'Initial'.
IMPORTTEXT3FROMMEMORYID'text'.
WRITE:
/SY-SUBRC,TEXT3.
IMPORTTEXT2TOTEXT1FROMMEMORYID'text'.
WRITE:
/SY-SUBRC,TEXT1.
SAPMZTS3的示例:
PROGRAMSAPMZTS3.
DATAJTABLIKESBOOKOCCURS10WITHHEADERLINE.
IMPORTITABTOJTABFROMMEMORYID'table'.
LOOPATJTAB.
WRITE/JTAB-BOOKID.
ENDLOOP.
输出位于两个连续的屏幕上,如下所示:
和
SAPMZTS2试图从数据簇“文本”中读取不存在的数据对象TEXT3。
因此,目标字段TEXT3保持不变。
现有数据对象TEXT2被放到TEXT1之后。
两种情况中,因为簇“文本”包含数据,SY-SUBRC都被设置为0。
SAPMZTS3将内表ITAB从簇“表”中写入内表JTAB。
两个表结构一样,同为ABAP/4词典表SBOOK结构。
4删除内存中的数据簇
要删除ABAP/4内存中的数据对象,请使用下列语句:
语法
FREEMEMORY[ID].
如果不附加ID,则此语句删除整个内存,包括此前用EXPORT存储到ABAP/4内存中的所有数据簇。
附加ID之后,该语句只删除用此名称命名的数据簇。
因为删除整个内存会导致任何系统例程内存内容的丢失,所以只应使用附加有ID的FREEMEMORY语句。
PROGRAMSAPMZTST.
DATA:
TEXT(10)VALUE'0123456789',
IDEN(3)VALUE'XYZ'.
EXPORTTEXTTOMEMORYIDIDEN.
TEXT='xxxxxxxxxx'.
IMPORTTEXTFROMMEMORYIDIDEN.
WRITE:
/SY-SUBRC,TEXT.
FREEMEMORY.
TEXT='xxxxxxxxxx'.
IMPORTTEXTFROMMEMORYIDIDEN.
WRITE:
/SY-SUBRC,TEXT.
此示例的输出为:
00123456789
4xxxxxxxxxx
FREEMEMORY语句删除数据簇“XYZ”。
因此,在下一个IMPORT语句之后,系统字段SY-SUBRC被设置为4,而目标字段保持不变。
5数据库中的数据簇
可以将数据簇存储到ABAP/4词典的特定数据库中。
就是所谓的ABAP/4簇数据库,其预定义结构为:
该方法允许单步存储任何具有深结构的复杂数据对象,而不必将其调整为关系数据库的平面结构。
这样,在整个系统中都可使用该数据对象,并且每个用户都可对其进行访问。
要使访问成功,必须知道存储对象的数据类型。
在簇数据库中存储数据,对于支持有关关系数据库信息的分析结果十分有用。
例如,如果要从所有分支机构的人员数据中生成销售额最高的客户清单或者完整的通讯录,就可以编写ABAP/4程序,让程序来解决此类问题,并将结果存储为数据簇。
如果需要刷新存储的数据簇,可以在后台定期运行这些程序。
要使用该结果,可以使用只访问该数据簇的其他程序。
因为不必在每次使用结果时都访问关系数据库中的分布式数据,并且也不必每次都重新生成结果,所以,此方法可以很大程度上减少系统的响应时间。
存储数据簇是专就ABAP/4而言。
尽管也可以使用SQL语句访问簇数据库,但是,只有ABAP/4语句能够对已存储的数据簇结构进行解码。
使用EXPORTTODATABASE语句将数据对象存储到簇数据库中。
使用IMPORTFROMDATABASE语句为数据簇生成目录表,并从簇数据库中读取数据对象。
使用DELETEFROMDATABASE语句从簇数据库中删除数据簇。
关于使用开放式SQL语句访问簇数据库的信息,参见
5簇数据库
簇数据库是ABAP/4词典中的特殊数据库。
用于存储数据簇。
其行结构被划分为部分标准化的开始区(由多个字段组成)和一个用于存储数据的大的区域。
下列主题介绍建立簇数据库的规则,同时还就系统定义的簇数据库INDX进行讨论。
6簇数据库的结构
簇数据库的结构如下所示:
建立簇数据库的规则如下所述。
必须创建第一点到第四点中列出的关键字段。
上述数据类型都是ABAP/4词典类型。
1.如果该表是针对客户的,第一个字段必须这样定义:
名称为MANDT,类型为CHAR,长度为3字节,用于存储客户ID。
存储数据簇时,系统既可自动使用当前客户填写字段MANDT,还可使用EXPORT语句中显式指定的客户进行填写。
2.下一字段(对于与客户无关的表,这是第一个字段)必须这样定义:
名称为RELID,类型为CHAR,长度为2字节。
该字段包含区域ID。
簇数据库被分成不同的区域。
存储数据簇时,系统用EXPORT语句中指定的区域ID填写字段RELID。
3.下一字段类型为CHAR,长度可变。
它包含簇的名称,存储数据簇时,在程序中用EXPORT语句的附加ID指定了该簇。
因为后面的字段要对齐,所以系统应最多使用3个未用字节填充在字段RELID的结尾。
如果创建自己的簇数据库,应该相应地定义此字段的长度。
4.下一字段必须名称为SRTF2,类型为INT4,长度为4。
单个数据簇可以扩展到数据库表的好几行中。
在理论上,每个簇可能有2**31行。
字段SRTF2包含存储的数据簇内行的顺序号码,可以是0和2**31-1之间的任何值。
存储数据簇时,系统自动填写此字段(参见第7点)。
5.SRTF2的后面可以是任何数目的数据字段,这些字段名称和类型可任意交换。
存储数据簇时,系统并不自动填写这些字段。
必须在程序中的EXPORT语句之前将值显式分配到这些字段。
通常包含诸如程序名、用户ID等控制信息。
6.行上的倒数第二个字段名称必须为CLUSTR,类型为INT2,并且长度必须为2。
它包含后面的字段CLUSTD中的数据长度。
存储数据簇时,系统自动填写此字段。
7.行上的最后一个字段必须名称为CLUSTD,类型为VARC。
其长度可以任意,但通常为1000个字节左右。
存储数据簇时,系统按压缩格式用实际数据填写此字段。
如果CLUSTD的长度不足以存储簇数据,则数据就被分布到多行上。
这些行在字段SRTF2中进行编号(参见上面的第4点)。
既可以按照上述规则创建自己的簇数据库(此时参见文档ABAP/4词典(页Error!
Notavalidlink.)),也可以使用系统定义的簇数据库INDX:
簇数据库的示例(页7)
7簇数据库的示例
数据库INDX是簇数据库的示例,是系统中所包含的标准安装的一部分。
从用户应用的角度考虑,由于没有必要先创建新的簇数据库,所以,比较实用。
而且,所有用户都可以访问存储在这里的数据,并且还可更改或删除。
要在ABAP/4编辑器中查看数据库INDX的结构,请选择“编辑->详细功能->命令条目”,然后输入SHOWINDX,或者双击INDX,例如在TABLES语句中。
对于每个字段,都将看到ABAP/4词典数据类型和相应的ABAP/4编程语言的数据类型(也就是TABLES生成的表工作区中的组件数据类型)。
头四个字段是表INDX的关键字段,并且与簇数据库的结构(页6)中介绍的完全相同。
此处簇名的第三个字段的名称是SRTFD,长度为22字节,也就是说,对于INDX,ABAP/4程序中以EXPORT语句的附加ID指定的名称最多可以有22个字符。
后七个字段是非标准字段,用于用户输入,例如:
_AEDAT:
最后修改的日期
_USERA:
用户名
_PGMID:
程序名
最后两个字段也是预定义的。
在表INDX中,存储实际数据簇的字段CLUSTD的长度为2886个字节。
有关表INDX用法的示例,参见
在簇数据库中存储数据对象(页7)
创建数据簇目录表(页9)
从簇数据库中读取数据对象(页10)
从簇数据库中删除数据簇(页12)
7在簇数据库中存储数据对象
要在簇数据库中存储ABAP/4程序的数据对象,请使用下列语句:
语法
EXPORT[FROM][FROM]...
TODATABASE()[CLIENT]ID.
此语句将列表中指定的数据对象存储为簇数据库中的簇。
必须用TABLES语句对加以声明。
如果不附加FROM,则将数据对象存储在自己的名称之下。
如果有附件项,则将数据对象存储到名称之下。
是存储数据库的簇的两字符区域ID。
(参见簇数据库的结构(页Error!
Notavalidlink.)簇数据库的结构(页Error!
Notavalidlink.)下的第2点)。
标识数据库中的数据,其最大长度取决于中名称字段的长度。
(参见簇数据库的结构(页6)下面的第3点)。
在处理特定客户的簇数据库时可以使用选项CLIENT关闭自动客户处理,然后自己指定客户。
必须在指定数据库名称之后立即指定此选项。
(参见簇数据库的结构(页6)下面的第1点)。
EXPORT语句也将表工作区的用户字段内容传输到数据库表。
根据需要,可以预先填写这些字段。
(参见簇数据库的结构(页6)下面的第5点)。
在具有相同名称的相同工作区和相同客户系统中,EXPORT语句总是完全改写任何现有数据簇的内容。
对于含有表头行的内表,只可以存储表本身,而不能存储表头行。
在EXPORT语句中,将表名解释为表。
这是例外。
通常将表名解释为表工作区(参见访问内表(页8–4))。
PROGRAMSAPMZTS1.
TABLESINDX.
DATA:
BEGINOFITABOCCURS100,
COL1TYPEI,
COL2TYPEI,
ENDOFITAB.
DO3000TIMES.
ITAB-COL1=SY-INDEX.
ITAB-COL2=SY-INDEX**2.
APPENDITAB.
ENDDO.
INDX-AEDAT=SY-DATUM.
INDX-USERA=SY-UNAME.
INDX-PGMID=SY-REPID.
EXPORTITABTODATABASEINDX(HK)ID'Table'.
WRITE:
'SRTF2',
AT20'AEDAT',
AT35'USERA',
AT50'PGMID'.
ULINE.
SELECT*FROMINDXWHERERELID='HK'
ANDSRTFD='Table'.
WRITE:
/INDX-SRTF2UNDER'SRTF2',
INDX-AEDATUNDER'AEDAT',
INDX-USERAUNDER'USERA',
INDX-PGMIDUNDER'PGMID'.
ENDSELECT.
使用3000行填写了内表ITAB,并且,在给INDX的某些用户字段赋值之后,ITAB被输出到INDX。
因为INDX是关系数据库,所以可以使用开放式SQL语句定位单独行。
使用SELECT语句,辅以适当的WHERE条件就可选择用EXPORT存储的行。
数据库字段的输出如下所示:
其中,输出表明用户字段AEDAT、USERA和PGMID由EXPORT传送,并且包含ITAB的数据簇扩展了6行。
如果在DO语句中更改数目3000,则此数据簇占用的行数也会发生变化。
9创建数据簇目录表
要从ABAP/4簇数据库中创建数据簇目录表,请使用下列语句:
语法
IMPORTDIRECTORYINTO
FROMDATABASE()
[CLIENT]ID.
此语句在存储于数据库中的数据簇中创建一系列数据对象,并将其放到表中。
必须使用TABLES语句声明。
要将数据簇存储到数据库中,通常使用EXPORTTODATABASE语句(参见在簇数据库中存储数据对象(页7))。
关于数据库表结构的详细信息,参见簇数据库的结构(页6)。
是即将存储数据库的簇的两字符ID。
标识数据库中的数据,其最大长度取决于中名称字段的长度。
在处理特定客户的簇数据库时,可以使用选项CLIENT关闭自动客户处理,然后自己指定客户。
必须在指定数据库名称之后立即指定此选项。
IMPORT语句也自动从数据库表中读取表工作区的用户字段内容。
如果可以创建某个目录表,则把SY-SUBRC设置为0。
否则,设置为4。
必须按照ABAP/4词典结构CDIR建立内表。
为此,请使用DATA语句的附件LIKE(参见DATA语句的基本格式(页3–14))。
结构CDIR包含下列组件:
字段名
类型
说明
NAME
CHAR
在簇中存储的对象名称
OTYPE
CHAR
对象类型:
F表示基本字段
R表示字段串
T表示内表
FTYPE
CHAR
对象的数据类型。
结构化的数据类型是类型C。
TFILL
INT4
已填写行的数目(针对内表)。
FLENG
INT2
字段或结构的长度。
PROGRAMSAPMZTS2.
TABLESINDX.
DATADIRTABLIKECDIROCCURS10WITHHEADERLINE.
IMPORTDIRECTORYINTODIRTABFROMDATABASE
INDX(HK)ID'Table'.
IFSY-SUBRC=0.
WRITE:
/'AEDAT:
',INDX-AEDAT,
/'USERA:
',INDX-USERA,
/'PGMID:
',INDX-PGMID.
WRITE/'Directory:
'.
LOOPATDIRTAB.
WRITE:
/DIRTAB-NAME,DIRTAB-OTYPE,DIRTAB-FTYPE,
DIRTAB-TFILL,DIRTAB-FLENG.
ENDLOOP.
ELSE.
WRITE'Notfound'.
ENDIF.
此程序创建数据簇的目录表,该数据簇