Database Cursor是一个资料库暂存区, 将经SELECT指令读取的记录存放至此暂存区, 再由此暂存区放至Work Area中, 可减少资料库读取的次数.
1.开启 Database Cursor
语法:
OPEN CURSOR <c> FOR SELECT … WHERE <condition>
Example:
TABLES SPFLI.
DATA: WA LIKE SPFLI,
C1 TYPE CURSOR.
OPEN CURSOR C1 FOR SELECT * FROM SPFLI
WHERE AREA ='TAIWAN'.
2.读取 Database Cursor的资料存入 Work Area
语法:
FETCH NEXT CURSOR <c> INTO <wa>
Example:
FETCH NEXT CURSOR C1 INTO WA.
读取下一笔Cursor位置的资料存入WA, 如果已无资料可读, SY-SUBRC <>0.
关闭 Database Cursor
语法:
CLOSE CURSOR <c>
Example:
CLOSE CURSOR C1.
*-------------------------------------------------------------------------------------*
COMMIT WORK & ROLLBACK WORK
要确定资料成功写入资料库,可使用COMMIT WORK指令,如:
COMMIT WORK.
相反的,如果反悔要复原,可使用 ROLLBACK WORK, 可复原在上个COMMIT WORK指令之后的资料, 如:
ROLLBACK WORK.
*-------------------------------------------------------------------------------------*
使用NATIVE SQL指令
语法格式:
EXEC SQL [PERFORMING <form>].
<statements>
ENDEXEC.
举例一.
EXEC SQL.
CREATE TABLE AVERI_CLNT (
CLIENT CHAR(3) NOT NULL,
ARG1 CHAR(3) NOT NULL,
ARG2 CHAR(3) NOT NULL,
FUNCTION CHAR(10) NOT NULL,
PRIMARY KEY (CLIENT, ARG1, ARG2)
)
ENDEXEC.
爱ERP网 www.loveerp.com
举例二.
DATA: F1(3), F2(3), F3(3).
F3 = ' 1 '
EXEC SQL.
SELECT CLIENT, ARG1 INTO :F1, :F2 FROM AVERI_CLNT
WHERE ARG2 = :F3
ENDEXEC
PERFORMING <form name>的使用:
如果NATIVE SQL的SELECT命令执行结果是抓到多笔记录,我们想要逐笔记录处理时,就用PERFORMING 参数,这个FORM能被逐次调用。如果想中止调用,就用EXIT
FORM SQL结束调用。
例如:
DATA: F1(3), F2(3), F3(3).
F3 = '010'
EXEC SQL PERFORMING WRITE_AVERI_CLNT.
SELECT CLIENT, ARG1 INTO :F1, :F2 FROM AVERI_CLNT
WHERE ARG2 = :F3
ENDEXEC.
FORM WRITE_AVERI_CLNT.
WRITE: / F1, F2.
ENDFORM.
DATA: BEGIN OF WA,
NAME(8),
AGE TYPE I,
END OF WA.
DATA F1 TYPE I.
FI = 20.
EXEC SQL PERFORMING OUTPUT.
SELECT NAME,AGE INTO :WA FROM NAME_TABLE
WHERE AGE >= :F1.
ENDEXEC..
FORM OUTPUT.
WRITE: / WA-NAME,WA-AGE.
ENDFORM.
注意:
a. NATIVE SQL把TABLE中的MANDT(client)栏位当作一般栏位使用,所以在抓取资料时必须指定特定的Client;
b. NATIVE SQL中的SELECT语句没有CHECK权限的功能;
c. 在登入SAP R/3系统时,我们已经自动与Database连接,所以在执行NATIVE SQL时并不需要CONNECT语句;
d. 一条NATIVE SQL语句可以以分号;结束,一般情况下是以句号.结束.
e. 某些数据库系统对TABLE名字和FIELD名字有大小写区别,要正确书写.
f. 在NATIVE SQL中,双引号"不表示注释.
*-------------------------------------------------------------------------------------*
结果语句
条件述叙
1. IF 述叙
语法:
IF <Condition1>.
<Statement 1 >
ELSEIF <Condition2>.
<Statement 2>
ELSEIF <Condition3>.
<Stetement 3>
…..
ELSE.
<else Statement >
ENDIF.
(1).在每个判断关键字之后要加上 .
(2).在巢状循环之中无法使用 ELSE 关键字, ELSE 关键字属 IF 关键字
Example:
IF 3 > 8.
WRITE / '3 is less than 8'.
ENDIF.
2. CASE 关键字
语法:
CASE <变量f>.
WHEN <Value1>.
<Statement1>
WHEN <Value2>.
<Statement2>
….
WHEN OTHERS.
<others Statement>
ENDCASE.
Example:
S = 'A'.
CASE S.
WHEN 'X'.
WRITE / 'String is X'.
WHEN OTHERS.
WRITE / 'String is not X'.
ENDCASE.
循环关键字
1.计次循环
语法:
DO [n TIMES] [VARYING <f> FROM <start> TO <end>.
<loop block>
ENDDO.
Example:
DO 2 TIMES.
WRITE / 'X'.
ENDDO.
执行结果:
X
X
DO VARYING I FROM 1 TO 10.
S = S + I.
ENDDO.
WRITE: / ,'1+2+3+…+10=',S
执行结果: 1+2+3+…+10=55
2.条件循环
语法:
WHILE <Condition>.
<Statement Block>
ENDWHILE
Example:
I = 1.
S=0.
WHILE I <= 10.
S = S+I.
I=I+1.
ENDWHILE.
WRITE: / ' 1+2+3+…+10=',S.
执行结果为: 1+2+3+…+10=55
循环控制关键字
1. CONTINUE
跳至循环的下一次
Example:
DO 3 TIMES.
IF SY-INDEX = 2.
CONTINUE.
WRITE / SY-INDEX.
ENDDO.
执行结果:
1
3
2. CHECK <Condition>
CHECK 之后条件成立才继续往下执行循环
Example:
DO 5 TIMES.
CHECK SY-INDEX BETWEEN 2 AND 4.
WRITE / SY-INDEX.
ENDDO.
执行结果:
2
3
4
3. EXIT
跳离循环关键字
Example:
DO 10 TIMES.
IF SY-INDEX = 4.
EXIT.
ENDIF
WRITE / SY-INDEX.
ENDDO.
执行结果:
1
2
3
无穷循环
DO .
<Statement Block>
ENDDO.
无穷循环必须配合 EXIT 关键字来执行
*-------------------------------------------------------------------------------------*
搜索字符串
要搜索特定模式的字符串,请使用 SEARCH 语句,用法如下:
语法
SEARCH <c> FOR <str> <options>.
该语句在字段 <c> 中搜索<str> 中的字符串。如果成功,则将 SY-SUBRC 的返回代码值设置为0并将 SY-FDPOS 设置为字段 <c> 中该字符串的偏移量。否则将
SY-SUBRC 设置为4。
搜索串 <str> 可为下列格 之一:
<str> 目 的
<pattern> 搜索 <pattern>( 任何字符顺序)。忽略尾部空格。
.<pattern>. 搜索 <pattern> ,但是不忽略尾部空格 。
*<pattern> 搜索以 <pattern> 结尾的词。
<pattern>* 搜索以 <pattern> 开始的词。
单词之间用空格、逗号、句号、分号、冒号、问号、叹号、括号、斜杠、加号和等号等分隔 。
DATA STRING(30) VALUE 'This is a little sentence.'.
WRITE: / 'Searched', 'SY-SUBRC', 'SY-FDPOS'.
ULINE /1(26).
SEARCH STRING FOR 'X'.
WRITE: / 'X', SY-SUBRC UNDER 'SY-SUBRC',
SY-FDPOS UNDER 'SY-FDPOS'
SEARCH STRING FOR 'itt '.
WRITE: / 'itt ', SY-SUBRC UNDER 'SY-SUBRC',
SY-FDPOS UNDER 'SY-FDPOS'
SEARCH STRING FOR '.e .'.
WRITE: / '.e .', SY-SUBRC UNDER 'SY-SUBRC',
SY-FDPOS UNDER 'SY-FDPOS'.
SEARCH STRING FOR '*e'.
WRITE: / '*e ', SY-SUBRC UNDER 'SY-SUBRC',
SY-FDPOS UNDER 'SY-FDPOS'.
SEARCH STRING FOR 's*'.
WRITE: / 's* ', SY-SUBRC UNDER 'SY-SUBRC',
SY-FDPOS UNDER 'SY-FDPOS'.
该过程的输 出如下:
SEARCHED SY-SUBRC SY-FDPOS
X 4 0
itt 0 11
.e . 0 15
*e 0 10
s* 0 17
搜索字符字段 <c> 的各种选项 (<options>)如下
ABBREVIATED
在字段 <c> 中搜索包含 <str> 中指定字符串的单词, 其中字符可能被其它字符隔开。单词和字符串的第一个字母必须相同 。
STARTING AT <n1>
在字段 <c> 中搜索从 <n1> 开始的 <str>。结果 SY-FDPOS 参照相对于 <n1> 的偏移量而不是字段的开始。
ENDING AT <n2>
在字段 <c> 搜索 <str> 直到位置 <n2>。
AND MARK
如果找到搜索串,则将搜索串中的所有字符(和使用 ABBREVIATED 时的所有字符)转换为大写形式。
DATA: STRING(30) VALUE 'This is a fast first example.',
POS TYPE I,
OFF TYPE I.
WRITE / STRING.
SEARCH STRING FOR 'ft' ABBREVIATED.
WRITE: / 'SY-FDPOS:', SY-FDPOS.
POS = SY-FDPOS + 2.
SEARCH STRING FOR 'ft' ABBREVIATED STARTING AT POS AND MARK.
WRITE / STRING.
WRITE: / 'SY-FDPOS:', SY-FDPOS.
OFF = POS + SY-FDPOS -1.
WRITE: / 'Off:', OFF.
该过程的输 出如下:
This is a fast first example.
SY-FDPOS: 10
This is a fast FIRST example.
SY-FDPOS: 4
Off: 15
请注意,在找到单词' fast' 之后,为了查找包含' ft'的第二个单词,必须在偏移量 SY-FDPOS 上加2,然后从位置 POS 开始查找。否则,会再次找到单词
'fast'。要获得' first' 相对于字段 STRING 开始的偏移量,从 POS 和 SY-FDPOS 计算。
获得字符串长度
要决定字符串到最后一个字符而不是 SPACE 的长度,请使用内部函数 STRLEN,用法如下:
语法
[COMPUTE] <n> = STRLEN( <c> ).
STRLEN 将操作数 <c> 作为字符数据类型处理,而不考虑其实际类型。不进行转换。
关键字 COMPUTE 可选。有关内部函数的详细信息,参见使用数学函数(页 49) 。
DATA: INT TYPE I,
WORD1(20) VALUE '12345'.
WORD2(20).
WORD3(20) VALUE ' 4 '.
INT = STRLEN( WORD1 ). WRITE INT.
INT = STRLEN( WORD2 ). WRITE / INT.
INT = STRLEN( WORD3 ). WRITE / INT.
结果分别是 5,0 和 4。
*-------------------------------------------------------------------------------------*
Standard Report
一个典型的报表程序是由许多的程序区块(Code Block)所组成,在区块间最好能加上一些说明以利程序可读性,一个典型的报表程序格式如下:
* PROGRAM SOURCE HEADER : 说明程序名称及目的
* Program Name:
* Description:
* Date/Author:
* Table Update:
* Special Logic:
* Include:
*-------------------------------------------------------------------------------------*
* MODIFICATION LOG : 程序修改更新记录
*-------------------------------------------------------------------------------------*
* ChangeDate Programmer Request Description
*-------------------------------------------------------------------------------------*
* NEW PROGRAM
*-------------------------------------------------------------------------------------*
* REPORT NAME : 声明程序名称及报表格式,
*-------------------------------------------------------------------------------------*
REPORT Z_____
NO STANDARD PAGE HEADING
MESSAGE-ID __ " 所使用的MESSAGE
LINE-COUNT ___ " 每页报表列数
LINE-SIZE ___. " 每页报表宽度
* TABLE DESCRIPTION : 声明程序会使用的TABLE
*-------------------------------------------------------------------------------------*
TABLES:
* DATA : 声明程序所使用的变量及自定型态
*-------------------------------------------------------------------------------------*
TYPES:
DATA:
* SELECTION SCREEN / OPTION / PARAMETER : 屏幕输入报表筛选条件
*-------------------------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK ____
SELECT-OPTIONS:
SELECTION-SCREEN END OF BLOCK ___
* INITIALIZATION : 启动程序开始执行, 如SELECT-OPTION及PARAMETER
*-------------------------------------------------------------------------------------*
INITIALIZATION.
INCLUDE ____.
* AT START SELECTION : 输入结束后启动的区块, 如按下<F8>
*-------------------------------------------------------------------------------------*
START-OF-SELECTION.
SET PF-STATUS ____. " 指定报表执行时所用的 GUI-STATUS名称
PERFORM READ_DATA.
PERFORM PROCESS_DATA.
PERFORM PRINT_DATA.
PERFORM PRINT_SUMMARY.
* AT USER Commaand : 执行在GUI-STATUS中自定的命令
*-------------------------------------------------------------------------------------*
AT USER_COMMAND.
* AT LINE SELECTION : 由在报表中按下<F2>或Double-Click启动
*-------------------------------------------------------------------------------------*
AT LINE-SELECTION.
* TOP OF PGAE : 每页开始列印时执行, 用于定义报表表头
*-------------------------------------------------------------------------------------*
* END OF PAGE : 报表列印完最后一页后启动
*-------------------------------------------------------------------------------------*
END-OF-PAGE
* END OF SELECTION : 在结束列印资料后启动, 如可用来印出USER输入的条件
*-------------------------------------------------------------------------------------*
END-OF-SELECTION.
INCLUDE _____
* FORM : 撰写程序中所使用到的副程序
*-------------------------------------------------------------------------------------*
* Read Data : 自TABLE读取资料放入Internal Table
*-------------------------------------------------------------------------------------*
FORM READ_DATA.
SELECT * FROM ______
INTO _______
WHERE _______.
IF SY-SUBRC = 0.
ENDIF.
APPEND _____. " 增加Internal Table元素
ENDSELECT.
ENDFORM.
* Process Data : 处理Internal Table的资料, 如排序及汇总
*-------------------------------------------------------------------------------------*
FORM PROCESS_DATA.
ENDFORM.
* Print Data : 依序输出 Internal Table的资料
*-------------------------------------------------------------------------------------*
FORM PRINT_DATA.
ENDFORM.
* Print Summary : 印出数值资料加总
*-------------------------------------------------------------------------------------*
FORM PRINT_SUMMARY.
ENDFORM.
* Include Program : 列出所含入的其它程序source code, 如副程序
*-------------------------------------------------------------------------------------*
INCLUDE _____
INCLUDE _____
*-------------------------------------------------------------------------------------*
*
REPORT rep.
Additions:
1. ... NO STANDARD PAGE HEADING
2. ... LINE-SIZE col
3. ... LINE-COUNT n(m)
表单输出每页由n行,其中的m行作为页脚;
4. ... MESSAGE-ID mid 消息对象
5. ... DEFINING DATABASE ldb
使用逻辑数据库,自动产生
*
事件块
INITIALIZATION
AT SELECTION-SCREEN
START-OF-SELECTION
GET
END-OF-SELECTION
TOP-OF-PAGE
END-OF-PAGE
*
事件块的简单处理过程:
*
ABAP程序运行的时候,INITIALIZATION首先被调用;
经过初始化的输入屏幕会显示在表示服务器;
用户离开输入屏幕的时候,START-OF-SELCTION事件会被自动调用;
结果数据会以列表的形式显示在第二个屏幕上;
*
源代码中的事件块顺序不影响它们的执行顺序
*
事件块编码规则(1)
INITIALIZATION
通常在此事件块中设定输入屏幕字段的初始值
*
事件块编码规则(2)
AT SELECTION-SCREEN
通常在此事件块中进行用户输入数据的合法性检查,发现错误则以消息的形式给出警示,直到用户输入正确的数值
例如: AT SELECTION-SCREEN .
IF P_DATE = SPACE .
MESSAGE E001 .
ENDIF.
效果:如果字段P_DATE为空,则程序会用消息001“日期字段不能为空!”来提示用户必须输入一个日期。而且输入屏幕会等待用户输入,知道该字段数值合
法
*
事件块编码规则(3)
START-OF-SELCTION
通常在此事件中针对业务需求进行系统数据的查询
例如:
start-of-selection .
perform get_data_for_oil .
效果:
在输入屏幕用户按下执行按钮后,子程序get_data_for_oil被执行,在其中获得业务相关的数据存放到内表或者其它变量,这些数据在END-OF-SELECTION事
件块中被输出
*
事件块编码规则(4)
END-OF-SELCTION
通常在此事件中进行结果清单的输出
例如:
end-of-selection .
write : 23(1) sy-vline,
24(20) tab-gas_plan right-justified ,
效果:
数据以清单的形式输出
*
事件块编码规则(5)
GET
从逻辑数据库中得到数据(较少用)
TOP-OF-PAGE
在此事件块中设计输出清单的页头
TOP-OF-PAGE
write : /1(240) '汽柴油日出厂情况表' centered .
write : /20(8) '日期:' ,
29(10) s_date ,
180(6) '单位:' ,
190(10) '吨' .
*
事件块编码规则(6)
END-OF-PAGE
在此事件中设定输出清单的页脚
例如:
END-OF-PAGE .
Write : ‘制作人’ , p_name .
*-------------------------------------------------------------------------------------*
*
比较所有的字段类型
要比较所有的字段类型,可以在逻辑表达式中使用下列运算符:
<运算符> 含义
EQ 等于
= 等于
NE 不等于
<> 不等于
>< 不等于
LT 小于
< 小于
LE 小于等于
<= 小于等于
GT 大于
> 大于
GE 大于等于
>= 大于等于