ABAP 基础知识访问外部数据库开发篇

作者:ABAP技巧与实战 约 8 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, 开发
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

原创 无峰 [ ABAP 技巧与实战 ](javascript:void\(0\);)

**点击蓝字** 关注我们

前言

前文讲解了怎么配置连接外部数据库

> 详见链接 无峰,公众号:ABAP 技巧与实战 [ ABAP基础知识 访问外部数据库-配置篇

> ](http://mp.weixin.qq.com/s?__biz=Mzg4MjA1MjE4NQ==&mid=2247486675&idx=1&sn=880947996ba5d9e851b666934c5d2f97&chksm=cf5dd1e5f82a58f3f4dfa774156a3853dcac4fc3950944ace75517dd689eceee2ca9aab19cb4#rd)

本文主要介绍通过ABAP语言访问外部数据库的几种方式

外部数据库配置

本文示例中的代码访问了两个外部数据库

MTD : 外部oracle数据库,其中示例表 ZTTEMP 字段( ZZTNO,WERKS)

S4Q : 外部HANA数据库(开发系统访问测试系统的数据库), 使用表USR02,ZTTEMP

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

ABAP访问外部数据库

通过ABAP访问外部数据库有四种方式.根据不同的情况,可以选择不同的方法.

• OPEN SQL访问

• NATIVE SQL 访问

• ADBC(ABAP Database Connectivity)

• AMDP ABAP Managed Database Procedures ? (未验证通过)

OPEN SQL直接访问

OPEN SQL 访问的限制条件:必须在ABAP数据字典中存在该表名,并且最好同目标系统表结构一致,

一般情况下,用来访问另外一个同版本的ECC数据库.当然,也可以把ECC的表定义语句在目标系统中创建一个同名同结构的表,然后用该方式访问.

直接访问时,在FROM TABLE 后面添加 CONNECTION s4q .

s4q是DBCO中建立的和另外一个S/4系统的连接

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

_**01** _

**报错及处理一**

可能的报错及处理方式

下图报错的原因是访问ORACLE数据库必须指定一个SCHEMA. 这个可以配置在连接参数中.

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

_**01** _

**报错及处理二**

出现下面的报错,表示系统尝试使用MANDT限制数据, 此时需要给OPEN SQL 语句添加CLIENT SPECIFIED 强制OPEN SQL

不要补充MANDT限制

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

NATIVE SQL访问

通过NATIVE SQL 访问外部数据库步骤

• 打开连接

• 执行SQL命令

• 关闭连接

_示例代码见文末_

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

_**01** _

**读取多条记录的方式**

• 游标方式 图一

• 非游标方式 图二

非游标方式其实隐式使用了游标.性能比游标方式要差.数据量小的时候看不出来. 大量数据读取就能看出二者的性能差异了.

图三是标准帮助中提示的优劣比较.

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图一

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图二

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图三

ADBC访问

ADBC(ABAP Database Connectivity) 是SAP提供的原生SQL(Native

SQL)接口API.可以通过ADBC执行任何数据库的原生SQL语句.

ABAP中有个标准的DEMO程序: ADBC_DEMO 演示了各种SQL语句的调用方式.图四的代码示例给出了SELECT语句的常用写法.

大概需要如下的过程

• 创建默认数据库的链接对象

• 创建一个查询对象

• 基于sql语句创建一个结果对象

• 定义传递结果集 一个数据对象-内表

• 获取数据内容

• 关闭连接

• 赋值数据到内表

_示例代码详见文末_

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

通过AMDP 访问?

AMDP ABAP Managed Database Procedures

标准ABAP帮助体系中提到访问外部数据库的方法中还有一种AMDP方式.为了完善本文,补充了一个AMDP访问外部数据库表的示例.(验证未通过)

尝试中发现AMDP只适用与HANA数据库. 并且尝试通过DEMO程序 DEMO_AMDP_CONNECTION 连接外部数据库S4Q. 尝试失败.

(报错见图四)

感觉AMDP 并不支持连接外部数据库.

图五中示例代码的连接 是 R/3*开头. 帮助中说S/3*是SERVICE CONNECT. 但是不理解有什么用处.

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图四

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图五

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

图六

总结

ABAP访问外部数据库的几种方式中. OPEN SQL 最简单,但是有很大局限性. NATIVE方式最简单易懂. 性能也最好. 但是不利于代码动态化.

ADBC 可以动态的实现数据的读取及内表的赋值.

前文DB02 SQL编辑器SQL语句自动生成报表 就采用了ADBC访问数据库的方法: 根据语句动态定义选择屏幕,动态定义内表, 读取的数据写入内表呈现.

> 详见链接 无峰,公众号:ABAP开发技巧 [ SAP工具箱之一键生成报表

> ](https://mp.weixin.qq.com/s?__biz=Mzg4MjA1MjE4NQ==&mid=2247484616&idx=1&sn=0ace84b7fb5a0faf1e468d7530538ef8&chksm=cf5dd9fef82a50e81f5d26d7a4cef2555d6ee5439428e25b554fa03363426dee1bfc26fdef56&token=1596155933&lang=zh_CN#rd)

该工具在付费文章中可以获取.

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

文中通过AMDP方式连接外部数据库的验证失败. 不推荐使用. 其它三种方式根据实际情况选择使用就好.

示例代码详见文末.

** THE **

** END **

**约定**

如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.

( **如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程.

越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.** )

ABAP 基础知识访问外部数据库开发篇 - 封面图
ABAP 基础知识访问外部数据库开发篇 - 封面图

**公众号 : syjf1976_abap**

**ABAP开发技巧**

**微信号 : 392077**

请微信联系管理员

syjf1976

sharry_xlp

Yannick_Duan 申请进入公众号讨论群

示例代码,OPEN SQL

*&---------------------------------------------------------------------**& Report ZTS_SQL_DBCO*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*REPORT zts_dbco_opensql.

PARAMETERS: p_s4 RADIOBUTTON GROUP ra1, p_ora RADIOBUTTON GROUP ra1. START-OF-SELECTION. CASE 'X'. WHEN p_s4.*访问另一个S4系统的同名表*需要注意的是,目标系统CLIENT和当前CLIENT 很可能不一样, 所以需要加上CLIENT SPECIFIED 避免CLIENT不同干扰数据获取 SELECT * FROM usr02 CLIENT SPECIFIED INTO TABLE @DATA(lt_usr02) BYPASSING BUFFER CONNECTION R/3*S4Q WHERE bname = '00177'. ."可以获取数据 DATA(lv_subrc) = sy-subrc . cl_demo_output=>write( lv_subrc ). cl_demo_output=>write( lt_usr02 ). cl_demo_output=>display( ). WHEN p_ora.*访问另一个其它系统的同名表*如果ABAP表有MANDT , 目标表没有, 则需要添加CLIENT SPECIFIED 避免系统自动添加MANDT 的限制条件,导致报错:字段MANDT不存在 DATA: BEGIN OF ls_temp, zztno(30), werks(4), END OF ls_temp. DATA: lt_temp LIKE TABLE OF ls_temp. SELECT zztno,werks FROM zttemp CLIENT SPECIFIED CONNECTION mtd INTO TABLE @lt_temp. cl_demo_output=>display( lt_temp ). ENDCASE.* COMMIT CONNECTION s4q. "在连接中提交.

示例代码 NATIVESQL

*&---------------------------------------------------------------------**& Report ZTS_SQL_DBCO*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*REPORT zts_dbco_nativesql.

PARAMETERS: p_1 RADIOBUTTON GROUP ra1, p_2 RADIOBUTTON GROUP ra1, p_3 RADIOBUTTON GROUP ra1, p_4 RADIOBUTTON GROUP ra1. DATA: BEGIN OF gs_temp, zztno(30), werks(4), END OF gs_temp.DATA: gt_temp LIKE TABLE OF gs_temp.DATA conn TYPE dbcon-con_name.

INITIALIZATION. %_p_1_%_app_%-text = 'SELECT方式一:DO循环读取游标,添加内表'. %_p_2_%_app_%-text = 'SELECT方式二:通过例程添加内表'. %_p_3_%_app_%-text = 'UPDATE:更新表内容'. %_p_4_%_app_%-text = 'INSERT:写入表内容'.

START-OF-SELECTION. conn = 'MTD'. "检查连接是否已经打开 EXEC SQL. SET CONNECTION :conn ENDEXEC. IF sy-subrc <> 0. "如果连接没有打开, 打开连接 EXEC SQL. CONNECT TO :conn ENDEXEC. ENDIF.

*两种方式: 方式一性能好于方式二 CASE 'X'. WHEN p_1. PERFORM frm_method_1. "SELECT方式一:DO循环读取游标,添加内表'. WHEN p_2. PERFORM frm_method_2. "SELECT方式二:通过例程添加内表'. when p_3. perform frm_update. when p_4. perform frm_insert. ENDCASE.

"关闭数据库连接 EXEC SQL. DISCONNECT :CONN ENDEXEC.

*输出结果 CASE 'X'. WHEN p_1 or p_2. cl_demo_output=>display( gt_temp ). ENDCASE.*&---------------------------------------------------------------------**& Form FRM_METHOD_1*&---------------------------------------------------------------------**& text*&---------------------------------------------------------------------**& --> p1 text*& <-- p2 text*&---------------------------------------------------------------------*FORM frm_method_1 . DATA: ls_temp LIKE gs_temp, lt_temp LIKE TABLE OF ls_temp. "执行SQL语句:通过open dbcur打开游标 EXEC SQL. OPEN dbcur FOR SELECT zztno,werks FROM zttemp ENDEXEC. "循环通过游标读取记录 " 两种赋值方式: " 1.按字段顺序赋值,select 字段与 INTO 字段顺序必须一致 " FETCH NEXT dbcur INTO :ls_TEMP-ZZTNO,:LS_TEMP-WERKS " 2.按结构整体赋值:select 字段必须与结构字段顺序一致,且字段长度一致. "

...

ABAP技巧与实战

关于作者:ABAP技巧与实战

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「ABAP基础知识访问外部数据库开发篇.md」整理生成,仅用于内部技术分享与学习交流。