文章目录
前言
在项目上遇到过几次SAP直接连接其他外围系统数据库,进行取数操作的需求,通常我们需要写SQL进行数据读取。一般是在SAP实施的项目初期,对数据大批量导入的时候,执行Select的时候进行这样的操作。
一、如何直连对方数据库?
通过SAP提供的标准功能ADBC,SAP提供了一些DEMO,关例子可以通过se38 ->输入ADBC*获取到,如下图
SAP提供标准的事务代码DBCO,可以对数据库信息进行配置,指定主机IP、数据库名即可
争对不同数据库,具体可参考如下链接中的配置——使用事务码DBCO实现SAP链接外部数据库以及读取例程
配置完成之后SE38->ADBC_TEST_CONNECTION,执行事务代码,可以测试数据库能否连接成功。
二、如何在代码中调用?
(以下内容提供一种思路,如果有更好的思路也可)
1.建立数据库连接 — Connect
代码如下:
*特定数据库连接,自建配置表,用来配置不同Client对应的数据库连接
SELECT SINGLE *
INTO ls_dbco
FROM zsy_db_xxx
WHERE field EQ xxx.
IF ls_dbco-con_name IS NOT INITIAL.
*DBCO中的数据库连接维护方式存在表DBCON中,用来校验是否存在此连接
SELECT SINGLE *
INTO ls_dbcon
FROM dbcon
WHERE con_name EQ ls_dbco-con_name.
IF sy-subrc NE 0.
MESSAGE e003(zxxx) WITH '数据库连接未维护,请联系系统管理员' RAISING sql_connection.
ELSE.
mv_dbms = ls_dbcon-dbms.
ENDIF.
CLEAR: lv_exception_text.
TRY.
*进行数据库连接
mo_sql_connection = cl_sql_connection=>get_connection( ls_dbco-con_name ).
CATCH cx_sql_exception INTO lo_sql_exception.
lv_exception_text = lo_sql_exception->sql_message.
IF lv_exception_text IS INITIAL.
lv_exception_text = lo_sql_exception->get_text( ).
ENDIF.
MESSAGE e003(zxxx) WITH lv_exception_text RAISING sql_connection.
ENDTRY.
ELSE.
MESSAGE e003(zxxx) WITH 'Client数据未维护,请联系系统管理员' RAISING sql_connection.
ENDIF.
2.插入数据 — Insert
( Tips:不推荐通过数据库直连的操作进行Insert处理,因为Insert很慢!很慢!很慢!>.<,影响效率。)
DATA:lv_statement TYPE string.
CLEAR: ev_severity, ev_message.
lv_statement = `INSERT INTO ` && iv_db_table
&& ` (` && mv_insert && `) `
&& ` VALUES(` && mv_values && `)`.
TRY.
"声明对应外围系统数据库所对应的表
DATA(lo_sql_statement) = mo_sql_connection->create_statement( tab_name_for_trace = iv_db_table ).
"插入的表结构
lo_sql_statement->set_param_table( io_data_insert ).
"调用组装的语句
lo_sql_statement->execute_update( lv_statement ).
ev_severity = 'S'.
ev_message = '插入数据成功'.
CATCH cx_sql_exception INTO DATA(lo_sql_exception).
ev_severity = 'E'.
IF lo_sql_exception->sql_message IS NOT INITIAL.
ev_message = lo_sql_exception->sql_message.
ELSE.
CASE lo_sql_exception->internal_error.
WHEN 1.
ev_message = 'SQL语句错误'.
WHEN 5.
ev_message = '数据库表对象不存在'.
WHEN 6.
ev_message = '数据库表对象已存在'.
WHEN 7.
ev_message = '数据库键值重复'.
WHEN 9.
ev_message = '数据库游标错误'.
WHEN 12.
ev_message = '数据库处理错误'.
WHEN 64.
ev_message = '数据库内存不足'.
WHEN OTHERS.
ev_message = '数据库内部错误'.
ENDCASE.
ENDIF.
CATCH cx_parameter_invalid INTO DATA(lo_parameter_invalid).
ev_severity = 'E'.
ev_message = lo_sql_exception->get_text( ).
ENDTRY.
3.更新数据 — Update
DATA: lv_statement TYPE string.
CLEAR: ev_severity, ev_message, ev_rows.
lv_statement = `UPDATE ` && iv_db_table
&& ` SET ` && mv_update
&& ` WHERE ` && mv_where.
TRY.
“声明对应外围系统数据库所对应的表
DATA(lo_sql_statement) = mo_sql_connection->create_statement( tab_name_for_trace = iv_db_table ).
”调用组装的语句
ev_rows = lo_sql_statement->execute_update( lv_statement ).
ev_severity = 'S'.
ev_message = '更新数据成功'.
CATCH cx_sql_exception INTO DATA(lo_sql_exception).
ev_severity = 'E'.
IF lo_sql_exception->sql_message IS NOT INITIAL.
ev_message = lo_sql_exception->sql_message.
ELSE.
CASE lo_sql_exception->internal_error.
WHEN 1.
ev_message = 'SQL语句错误'.
WHEN 5.
ev_message = '数据库表对象不存在'.
WHEN 6.
ev_message = '数据库表对象已存在'.
WHEN 7.
ev_message = '数据库键值重复'.
WHEN 9.
ev_message = '数据库游标错误'.
WHEN 12.
ev_message = '数据库处理错误'.
WHEN 64.
ev_message = '数据库内存不足'.
WHEN OTHERS.
ev_message = '数据库内部错误'.
ENDCASE.
ENDIF.
CATCH cx_parameter_invalid INTO DATA(lo_parameter_invalid).
ev_severity = 'E'.
ev_message = lo_sql_exception->get_text( ).
ENDTRY.
4.读取数据 — Select
DATA: lv_statement TYPE string.
CLEAR: ev_severity, ev_message.
lv_statement = `SELECT ` && mv_select
&& ` FROM ` && iv_db_table
&& ` WHERE ` && mv_where.
TRY.
“声明对应外围系统数据库所对应的表
DATA(lo_sql_statement) = mo_sql_connection->create_statement( tab_name_for_trace = iv_db_table ).
”调用组装的语句
DATA(lo_sql_result_set) = lo_sql_statement->execute_query( lv_statement ).
"抓取数据
lo_sql_result_set->set_param_table( eo_data_select ).
ev_rows = lo_sql_result_set->next_package( ).
lo_sql_result_set->close( ).
ev_severity = 'S'.
ev_message = '读取数据成功'.
CATCH cx_sql_exception INTO DATA(lo_sql_exception).
ev_severity = 'E'.
IF lo_sql_exception->sql_message IS NOT INITIAL.
ev_message = lo_sql_exception->sql_message.
ELSE.
CASE lo_sql_exception->internal_error.
WHEN 1.
ev_message = 'SQL语句错误'.
WHEN 5.
ev_message = '数据库表对象不存在'.
WHEN 6.
ev_message = '数据库表对象已存在'.
WHEN 7.
ev_message = '数据库键值重复'.
WHEN 9.
ev_message = '数据库游标错误'.
WHEN 12.
ev_message = '数据库处理错误'.
WHEN 64.
ev_message = '数据库内存不足'.
WHEN OTHERS.
ev_message = '数据库内部错误'.
ENDCASE.
ENDIF.
CATCH cx_parameter_invalid INTO DATA(lo_parameter_invalid).
ev_severity = 'E'.
ev_message = lo_sql_exception->get_text( ).
ENDTRY.
5.删除数据 — Delete
DATA: lv_statement TYPE string,
lv_fields_select TYPE string,
lv_fields_where TYPE string,
lo_sql_statement TYPE REF TO cl_sql_statement,
lo_sql_result_set TYPE REF TO cl_sql_result_set,
ls_fields_select TYPE zewm_s_sqlfields .
lv_statement = `DELETE FROM ` && iv_db_table && ` WHERE ` && mv_where .
“声明对应外围系统数据库所对应的表
lo_sql_statement = mo_sql_connection->create_statement( tab_name_for_trace = iv_db_table ).
”调用组装的语句
ev_rows = lo_sql_statement->execute_update( lv_statement ).
ev_severity = 'S'.
ev_message = '更新数据成功'.
CATCH cx_sql_exception INTO DATA(lo_sql_exception).
ev_severity = 'E'.
IF lo_sql_exception->sql_message IS NOT INITIAL.
ev_message = lo_sql_exception->sql_message.
ELSE.
CASE lo_sql_exception->internal_error.
WHEN 1.
ev_message = 'SQL语句错误'.
WHEN 5.
ev_message = '数据库表对象不存在'.
WHEN 6.
ev_message = '数据库表对象已存在'.
WHEN 7.
ev_message = '数据库键值重复'.
WHEN 9.
ev_message = '数据库游标错误'.
WHEN 12.
ev_message = '数据库处理错误'.
WHEN 64.
ev_message = '数据库内存不足'.
WHEN OTHERS.
ev_message = '数据库内部错误'.
ENDCASE.
ENDIF.
CATCH cx_parameter_invalid INTO DATA(lo_parameter_invalid).
ev_severity = 'E'.
ev_message = lo_sql_exception->get_text( ).
ENDTRY.
总结
以上就是DBCO的大致内容,本文仅仅简单介绍了数据库连接的简单使用,不同的数据库之间数据SQL的处理方式可能有些不同,需要按照实际内容板砖…