原文:Small Fire · ABAP 语法详解(SQL) · ABAP 子专栏 · Small Fire 技术笔记
Open SQL
ABAP可以通过两种方式与数据库交互
- Native SQL:数据库自身的SQL,可以直接访问数据库,不够安全。
- Open SQL:集成到ABAP中的标准SQL子集,通过SAP数据库接口识别不同的数据库,然后将语句进行转换成底层数据库对应的语言。
基本语法:与其他SQL语句类似,主要包括增删改查:Select、Update、Insert、Delete、Modify
<1> SELECT 语法
SELECT [SINGLE] <result> FROM <dbtab> :SINGLE表示查询单行数据
INTO <target> :内表或则结构
[INTO <f1>...<fn>] :将查询结果赋值到具体字段
[INTO CORRESPONDING FILES OF <itab>]
: 将查询结果按字段匹配赋值给具体的表或者结构体。
WHERE <condition> :查询条件
Group BY <fields> :分组查询条件
ORDER BY <fields>. :排序条件
表连接:
INNER JOIN:查询结果包含两个连接表中彼此相对应的数据记录。
LEFT OUTER JOIN:查询结果集中包含左表中的所有数据记录,右表中仅查询出包含相匹配的数据。
连接语句:
使用ON 和 AND 语句将左右两个表关联起来,一般使用主键;
INNER JOIN不能使用NOT、LIKE、IN;
LEFT OUTER JOIN只能使用 EQ;
WHERE语句:
至少有一个表达式的两个操作数分别来自于左右两个表,建立连接关系;
LEFT OUTER JOIN的右表字段不能在WHERE中使用;
以内表为查询条件:
SELECT <f1...fn> FROM <dbtab> FOR ALL ENTRIED IN <itab> WHERE <cond>.
使用 FOR ALL ENTRIED IN itab 前,一定要检查itab表是否为空,否则会造成SQL的执行效率极低。
获取限制读取数据的条数:前n条
SELECT * FROM <dbtab> INTO <itab> UP TO <n> ROWS.
标准函数:
COUNT():统计查询总数。
SUM():统计表中某个数值字段的总和。
AVG():统计表中某个数值字段的平均值。
MAX():统计表中某个字段的最大值。
MIN() :统计表中某个字段的最小值。
<2> UPDATE(修改更新操作)
UPDATE <dbtab> SET f1 = v1...fn = vn (WHERE <condition>).
UPDATE <dbtab> FROM <wa>.
UPDATE <dbtab> FROM TABLE <itab> (WHERE <condition>).
<3> INSERT(插入数据)
INSERT INTO <dbtab> VALUES <conditin>.
INSERT <dbtab> FROM <wa>.
INSERT <dbtab> FROM TABLE <itab>.
<4> DELETE(删除操作)
DELETE FROM <dbtab> WHERE <condition>.
DELETE <dbtab> FROM TABLE <itab>.
<5> MODIFY(修改操作,相当于Update & Insert)
MODIFY <dbtab> FROM <wa>.
MODIFY <dbtab> FROM TABLE <itab>.
Native SQL
EXEC SQL 和 ADBC 是所谓的 Native SQL,这种方式直接进入指定数据库,不涉及到 DBI,这样就没有 Table buffer。相对 EXEC SQL 来说,更推荐 ADBC 的方式执行 native sql,这种方式的好处是更加容易追踪错误。
连接其他的数据库 :TCode:DBCO
添加新的连接:MSSQL_SERVER=IP adress MSSQL_DBNAME=dbname OBJECT_SOURCE=dbname
注意事项:
Native SQL 语句不能有结尾符号;
EXEC SQL …… ENDEXEC间不能有注释;
参数占位符是冒号:;
程序调用 :
DATA: p_dbname(10) VALUE 'DBNAME',
DATA: l_sql_error TYPE REF TO cx_sy_native_sql_error,
error_text TYPE string.
...
内表数据准备
...
"连接数据库
TRY.
EXEC SQL.
CONNECT TO 'DBNAME'/ CONNECT TO :p_dbname
ENDEXEC.
EXEC SQL.
SET CONNECTION 'DBNAME'
ENDEXEC.
CATCH cx_sy_native_sql_error INTO l_sql_error.
CALL METHOD l_sql_error->get_text
RECEIVING
result = l_error_text.
ENDTRY.
IF sy-subrc <> 0.
WRITE: /1 ‘连接到数据库失败:’, l_error_text.
STOP.
ENDIF.
"执行SQL
TRY.
LOOP AT gt_room INTO gs_room.
EXEC SQL.
insert into ljc_room ( room_id, room_name, room_people, room_desc )
values(:gs_room-room_id, :gs_room-room_name, :gs_room-room_people, :gs_room-room_desc)
ENDEXEC.
ENDLOOP.
CATCH cx_sy_native_sql_error INTO l_sql_error.
error_text = l_sql_error->get_text( ).
ENDTRY.
"异常处理
IF l_error_text IS INITIAL.
EXEC SQL.
commit.
ENDEXEC.
ELSE.
CLEAR l_error_text.
EXEC SQL.
rollback
ENDEXEC.
ENDIF.
"断开连接
EXEC SQL.
DISCONNECT :p_dbname
ENDEXEC.
游标使用:
DATA : arg1 TYPE string VALUE '800' .
TABLES : t001 .
EXEC SQL .
OPEN c1 FOR " 打开游标
SELECT MANDT , BUKRS
FROM T001 " 远程数据库表
WHERE MANDT = :arg1 AND BUKRS >= 'ZA01'
ENDEXEC .
DO .
EXEC SQL .
FETCH NEXT c1 INTO :t001-mandt, :t001-bukrs "读取游标
ENDEXEC .
IF sy - subrc <> 0 .
EXIT .
ELSE .
WRITE : / t001-mandt, t001-bukrs .
ENDIF .
ENDDO .
EXEC SQL .
CLOSE c1 "关闭游标
ENDEXEC .
未完待续……ABAP 语法详解(优化)