ABAP操作外部数据库
Native SQL详解
介绍
Native SQL允许你针对数据库来使用原生的SQL,这些SQL可能是标准的SQL,也可以是某数据库特定的SQL。如果使用database-specific SQL语句,则数据库不能更换,否则请使用Open SQL。
本地SQL会绕过R/3 database interface,操作时不会记录日志,不会同步应用服务器上的database buffer。另外,使用ABAP Dictionary定义的类型为LCHR or LRAW的长列时,这些列需要使用Open SQL来读取,因为读取这些字段时,还需要使用另外存储此类型长列的长度信息,才能准确读出。最后,本地SQL是不会自动能客户端字段MANDT字段进行处理,该字段会像普通字段那样对待
创建数据库连接
T-CODE
:DBACOCKPIT
注:测试连接如果出错,可以用ADBC_TEST_CONNECTION 测试,ADBC_TEST_CONNECTION 测试后有个图标可以点进trace文件,拉到最后,就是出错的具体信息。
连接成功后可以用ADBC_QUERY查询表结构和数据
如果报错少文件
B B Loading DB library ‘/usr/sap/<SID>/D80/exe/dboraslib.so’ …
M *** ERROR => DlLoadLib()==DLENOACCESS - dlopen(“/usr/sap/<SID>/D80/exe/dboraslib.so”) FAILED
解决
2850410 - DBSL is missing during remote database connection to Oracle
基于CLASS的ADBC
- DBCO创建连接
- 使用CL_SQL_CONNECTION=>GET_CONNECTION
- 创建CL_SQL_STATEMENT实例;
- 调用execute_queryO实现NativeDBCal;
- 通过setparamOset_param_tableO取得结果集变量;
- 通过next_packageO方法取得结果集数据
查询
DATA: lo_sql TYPE REF TO cl_sql_statement,
lx_sql TYPE REF TO cx_sql_exception,
lo_result TYPE REF TO cl_sql_result_set,
lr_mh_id TYPE REF TO data,
lt_mh_id TYPE STANDARD TABLE OF typ_mh_id,
lt_mh_add_id TYPE STANDARD TABLE OF typ_mh_id.
CREATE OBJECT lo_sql EXPORTING con_ref = cl_sql_connection=>get_connection( is_dbcon ).
lo_result = lo_sql->execute_query( |SELECT app_task_id AS task_id FROM lnportal.epp_task WHERE app_id = 'sdln-erpep' | ).
GET REFERENCE OF lt_mh_id INTO lr_mh_id.
lo_result->set_param_table( lr_mh_id ).
lo_result->next_package( ).
lo_result->close( ).
NATIVE SQL
- Native SQL语句不能以句点号结尾;
- 不能在EXEC SQL…ENDEXEC间有注释,即不能有星号与双引号的出现
- 注意数据库系统大小写是否敏感
- 参数占位符使用冒号,而不是问号
判断是否已经连接
DATA: dbcname TYPE dbcon_name VALUE 'ERP2PORTAL'.
DATA lv_check TYPE dbcon_name.
lv_check = dbcname.
DATA: lc_exc_ref TYPE REF TO cx_sy_native_sql_error.
TRY.
EXEC SQL.
get connection :lv_check
ENDEXEC.
IF dbcname NE lv_check .
EXEC SQL.
connect to :dbcname
ENDEXEC.
IF sy-subrc <> 0.
WRITE: / '连接外部数据错误 '.
ELSE.
WRITE: / '连接外部数据成功 '.
ENDIF.
ENDIF.
** 关闭连接
EXEC SQL.
DISCONNECT :dbcname
ENDEXEC.
CATCH cx_sy_native_sql_error INTO lc_exc_ref.
* return-message = lc_exc_ref->get_text( ).
* return-type = 'E'.
ENDTRY.
查询
DATA: BEGIN OF ls_ddd occurs 0,
app_task_id(100),
receiver(100),
END OF ls_ddd.
"打开游标
EXEC SQL.
OPEN c1 FOR SELECT app_task_id,receiver FROM lnportal.epp_task
WHERE app_id = 'sdln-erpep'
ENDEXEC.
DO.
"读取游标
EXEC SQL.
FETCH NEXT c1 INTO :ls_ddd-app_task_id, :ls_ddd-receiver
ENDEXEC.
IF sy-subrc <> 0.
EXIT.
ELSE.
WRITE: / ls_ddd-app_task_id, ls_ddd-receiver.
APPEND ls_ddd.
ENDIF.
ENDDO.
"关闭游标
EXEC SQL.
CLOSE c1
ENDEXEC.
调用存储过程
EXECUTE PROCEDURE
参数以逗号分隔,并需要IN、OUT 来指定是输入还是输出参数,或者是使用INOUT来表示即是输入也是输出参数
EXEC SQL.
EXECUTE PROCEDURE proc1 ( IN :x, OUT :y )
ENDEXEC.