开发者日志:ABAP通过辅助数据库连接HANA
介绍
在HANA开发日志中,我对开发人员进入HANA世界的方法只是蜻蜓点水了一下。今天,我想描述下我过去几天研究了很久的场景:即在目前的环境下,从ABAP访问HANA。对于这一点,我想说的是目前可以建立的东西。我们都知道,SAP对于在HANA上运行ABAP特定功能已经有令人兴奋的计划,但是,每个人可能不知道的是当HANA作为ABAP系统的辅助数据库时,现在有什么可以做到的?这正是SAP如何构建现在的HANA加速器(方法),所以,花点时间来学习这些是如何建立以及ABAP环境中哪些开发选项支持该场景是很值得的。
HANA作为辅助数据库
我现在描述的场景在HANA的实施中是很常见的:你把HANA安装为辅助数据库,而不是替换了当前数据库。
然后你使用复制(replication)把数据的拷贝移至HANA系统中。你的ABAP程序得到加速,通过读取HANA而非本地数据库的数据。纵观本博客的其余部分,我想讨论如何执行加速读取的技术方案。
前提条件:
- SAP HANA客户端安装到了每个ABAP应用服务器,并且其操作系统必须支持HANA客户端(检查平台可用性矩阵(Platform Availability Matrix)支持的操作系统 )。
- SAP HANA DBSL 已安装(这是数据库特定的库,是ABAP内核的一部分)
- SAP HANA DBSL只在ABAP Kernel 7.20中可用
◦Kernel 7.20已经是NetWeaver 7.02, 7.03, 7.20, 7.30 and 7.31的内核
◦Kernel 7.20向下兼容,同时也适用NetWeaver 7.00, 7.01, 7.10, and 7.11 - 你的ABAP系统必须是Unicode
接下来,你的ABAP系统必须进行配置来连接到这个替代数据库。你有一个保存数据库连接字符串,用户名和密码的集中地方。然后你的应用只要指定使得数据库连接信息应用独立的配置键。
该配置可以通过对于表DBCON的表维护(SM30)实现。在配置屏幕上,您要提供DBMS类型(HANA为HDB),你要使用的所有连接和连接字符串的用户名和密码。务必包括HANA的系统端口号,应该是3<实例号>15,所以如果你的HANA的实例号为01,端口号就为30115。
DBCON也可以通过代码DBACOCKPIT来维护,最后你会得到和DBCON一样的记录,但是你会看到更多的信息(例如默认的模式等),然后你可以从那里测试连接。
通过Open SQL连接辅助数据库
从ABAP端执行辅助数据库的SQL操作最简单的方法是,使用ABAP开发人员已经熟悉的Open SQL语句。如果您提供CONNECTION额外的语法(dbcon),你可以强制在替代数据库执行Open SQL语句。
例如,我们拿一个简单的SELECT语句,然后在HANA上执行:
- SELECT * FROM sflight CONNECTION (‘AB1’)
- INTO TABLE lt_sflight
- WHERE carrid = ‘LH’.
这种方法的好处就是它的简单性。利用已存在的SQL语句一个小小的附加参数,你可以把你的操作重定向到HANA 中。缺点是你正在访问的表或视图必须存在于ABAP数据字典中。这对于加速器场景来说不是一个大问题,考虑到所有的数据都驻留在ABAP DBMS中并复制到HANA。这种情况下,我们总是在ABAP数据字典中有表的本地拷贝。这意味着,你不能访问特定的HANA程序,例如分析视图或是数据库存储过程。你也不能访问任何使用HANA作为主要持久层的表。
通过本地SQL连接辅助数据库
ABAP同样也有使用本地SQL的能力。这种情况下,你要写数据库相关的SQL语句。这使得你可以访问底层数据库中的表和其他工件(artifact)。本地SQL也有调用数据库过程的语法。如果我们拿上面的例子,可以用本地SQL来重写:
- EXEC SQL.
- connect to ‘AB1’ as ‘AB1’
- ENDEXEC.
- EXEC SQL.
- open dbcur for select * from sflight where mandt = :sy-mandt and carrid = ‘LH’
- ENDEXEC.
- DO.
- EXEC SQL.
- fetch next dbcur into :ls_sflight
- ENDEXEC.
- IF sy-subrc NE 0.
- EXIT.
- ELSE.
- APPEND ls_sflight TO lt_sflight.
- ENDIF.
- ENDDO.
- EXEC SQL.
- close dbcur
- ENDEXEC.
- EXEC SQL.
- disconnect ‘AB1’
- ENDEXEC.
这里代码当然比Open SQL多,也没有那么优雅,因为我们使用数据库的游标取得数据矩阵。但是好处是可以访问到否则没有的特点。例如,我可以把数据插入到HANA表中,然后使用HANA数据库序列号作为数的范围或是数据库内置的函数类似now()。
- EXEC SQL.
- insert into “REALREAL”.”realreal.db/ORDER_HEADER”
- values(“REALREAL”.”realreal.db/ORDER_SEQ”.NEXTVAL,
- :lv_date,:lv_buyer,:lv_processor,:lv_amount,now() )
- ENDEXEC.
- EXEC SQL.
- insert into “REALREAL”.”realreal.db/ORDER_ITEM” values((select max(ORDER_KEY)
- from “REALREAL”.”realreal.db/ORDER_HEADER”),0,:lv_product,:lv_quantity,:lv_amount)
- ENDEXEC.
另一个通过EXEC SQL使用本地SQL的坏处是,对于你建立的SQL语句没有任何语法检查。错误直到运行时才会捕捉,如果异常没有正确的处理会导致短时当机,这也使得测试很有必要。
通过本地SQL-ADBC 连接辅助数据库
第三个选择提供了通过EXEC SQL连接本地SQL的好处,也在某些限制上做了改进。这是ADBC-ABAP数据连接的概念。基本上,它是一系列类(CL_SQL*)简化和抽象了EXEC SQL区块。例如,我们再次重写我们的SELECT * FROM SFLIGHT example例子:
- ****Create the SQL Connection and pass in the DBCON ID to state which Database Connection will be used
- DATA lr_sql TYPE REF TO cl_sql_statement.
- CREATE OBJECT lr_sql
- EXPORTING
- con_ref = cl_sql_connection=>get_connection( ‘AB1’ ).
- ****Execute a query, passing in the query string and receiving a result set object
- DATA lr_result TYPE REF TO cl_sql_result_set.
- lr_result = lr_sql->execute_query(
- |SELECT * FROM SFLIGHT WHERE MANDT = { sy-mandt } AND CARRID = ‘LH’| ).
- ****All data (parameters in, results sets back) is done via data references
- DATA lr_sflight TYPE REF TO data.
- GET REFERENCE OF lt_sflight INTO lr_sflight.
- ****Get the result data set back into our ABAP internal table
- lr_result->set_param_table( lr_sflight ).
- lr_result->next_package( ).
- lr_result->close( ).
这里,我们至少去除了数据库游标的分步处理,取而代之的是把数据的整个包一次性读取到内表中。默认情况下,初始包的大小会返回所有结果记录的条数,但是你可以指定任何你想要的包大小,从而调整对大返回结果集的处理。对HANA场景中最重要的是ADBC使你可以访问非数据字典的工件,包括HANA存储过程。鉴于ADBC对于EXEC SQL的优势,SAP推荐总是尝试使用基于ADBC类的接口。
结束语
这还真的只是开始,你可以用这个加速器方法把ABAP集成到SAP HANA中。我在我例子中使用了最简单的SQL语句,以求更集中于技术整合是如何工作的细节。不过,当你执行更有力的语句(SELECT SUM … GROUP BY)、访问HANA特定的工件(如在OLTP表上的OLAP视图)或是存储过程,真正的威力才会显现。这些都是我将在未来我的博客中讨论的主题。
真正的ABAP开发不建议使用Native SQL,一般都是使用Open SQL,提高数据检索的效率。