从 ABAP 调用 SQLScript 的最佳方法是通过 AMDP 框架。该框架管理 SQLScript 对象的生命周期,并将其作为 ABAP 对象(类)嵌入。在 ABAP 端执行开发、维护和传输。AMDP 的调用对应于 ABAP 中的类方法调用。AMDP 框架负责生成和调用相应的数据库对象。
有关详细信息,请参阅 ABAP - 关键字文档 → ABAP - 参考 → 处理外部数据 → ABAP 数据库访问 → AMDP - ABAP 管理的数据库过程。
提示您可以使用可以使用内置命令 CALL DATABASE PROCEDURE 从 ABAP 本地调用的过程代理从 ABAP 调用 SQLScript。但是,建议使用 AMDP。
SQLScript 过程通常必须在 SAP HANA Studio 中使用 HANA 建模器创建。之后,可以使用面向 Eclipse 的 ABAP 开发工具创建过程代理。在过程代理中,可以调整 ABAP 和 HANA 数据类型之间的类型映射。过程代理通常通过 ABAP 传输系统进行传输,而 HANA 过程可在交付单元内作为 TLOGO 对象进行传输。
在 ABAP 中调用过程非常简单。以下示例显示使用两个输入(一个标量,一个表)和一个(表)输出参数调用过程:
CALL DATABASE PROCEDURE z_proxy
EXPORTING iv_scalar = lv_scalar
it_table = lt_table
IMPORTING et_table1 = lt_table_res.
使用 CALL DATABASE PROCEDURE 命令的 connection 子句,还可以使用辅助数据库连接调用数据库过程。有关如何使用 CALL DATABASE PROCEDURE 命令的详细说明,请参阅 ABAP 帮助,并可能引发异常。
还可以使用 ABAP API 以编程方式创建过程代理。有关此主题的详细信息,请参阅类 CL_DBPROC_PROXY_FACTORY 的文档。
有关详细信息,请参阅 ABAP - 关键字文档 → ABAP - 参考 → 处理外部数据 → ABAP 数据库访问 → ABAP 和 SAP HANA → 访问 SAP HANA XS 中的对象 → 访问 SAP HANA XSC 对象 → XSC 中 SQLScript 过程的数据库过程代理 → CALL DATABASE PROCEDURE。
*&---------------------------------------------------------------------*
*& Report ZRS_NATIVE_SQLSCRIPT_CALL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
report zrs_native_sqlscript_call.
parameters:
con_name type dbcon-con_name default 'DEFAULT'.
types:
* result table structure
begin of result_t,
key type i,
value type string,
end of result_t.
data:
* ADBC
sqlerr_ref type ref to cx_sql_exception,
con_ref type ref to cl_sql_connection,
stmt_ref type ref to cl_sql_statement,
res_ref type ref to cl_sql_result_set,
* results
result_tab type table of result_t,
row_cnt type i.
start-of-selection.
try.
con_ref = cl_sql_connection=>get_connection( con_name ).
stmt_ref = con_ref->create_statement( ).
***********************************
Setup test and procedure
*************************************
* Create test table
try.
stmt_ref->execute_ddl( 'DROP TABLE zrs_testproc_tab' ).
catch cx_sql_exception.
endtry.
stmt_ref->execute_ddl(
'CREATE TABLE zrs_testproc_tab( key INT PRIMARY KEY, value NVARCHAR(255) )' ).
stmt_ref->execute_update(
'INSERT INTO zrs_testproc_tab VALUES(1, ''Test value'' )' ).
* Create test procedure with one output parameter
try.
stmt_ref->execute_ddl( 'DROP PROCEDURE zrs_testproc' ).
catch cx_sql_exception.
endtry.
stmt_ref->execute_ddl(
CREATE PROCEDURE zrs_testproc( OUT t1 zrs_testproc_tab ) &&
READS SQL DATA AS &&
BEGIN &&
t1 = SELECT * FROM zrs_testproc_tab; &&
END
).
***********************************
Execution time
*************************************
perform execute_with_transfer_table.
perform execute_with_gen_temptables.
con_ref->close( ).
catch cx_sql_exception into sqlerr_ref.
perform handle_sql_exception using sqlerr_ref.
endtry.
form execute_with_transfer_table.
data lr_result type ref to data.
* Create transfer table for output parameter
* this table is used to transfer data for parameter 1 of proc zrs_testproc
* for each procedure a new transfer table has to be created
* when the procedure is executed via result view, this table is not needed
* If the procedure has more than one table type parameter, a transfer table is needed for each parameter
* Transfer tables for input parameters have to be filled first before the call is executed
try.
stmt_ref->execute_ddl( 'DROP TABLE zrs_testproc_p1' ).
catch cx_sql_exception.
endtry.
stmt_ref->execute_ddl(
'CREATE GLOBAL TEMPORARY COLUMN TABLE zrs_testproc_p1( key int, value NVARCHAR(255) )'
).
* clear output table in session
* should be done each time before the procedure is called
stmt_ref->execute_ddl( 'TRUNCATE TABLE zrs_testproc_p1' ).
* execute procedure call
res_ref = stmt_ref->execute_query( 'CALL zrs_testproc( zrs_testproc_p1 ) WITH OVERVIEW' ).
res_ref->close( ).
* read result for output parameter from output transfer table
res_ref = stmt_ref->execute_query( 'SELECT * FROM zrs_testproc_p1' ).
* assign internal output table
clear result_tab.
get reference of result_tab into lr_result.
res_ref->set_param_table( lr_result ).
* get the complete result set in the internal table
row_cnt = res_ref->next_package( ).
write: / 'EXECUTE WITH TRANSFER TABLE:', / 'Row count: ', row_cnt.
perform output_result.
endform.
form execute_with_gen_temptables.
* mapping between procedure output parameters
* and generated temporary tables
types:
begin of s_outparams,
param_name type string,
temptable_name type string,
end of s_outparams.
data lt_outparam type standard table of s_outparams.
data lr_outparam type ref to data.
data lr_result type ref to data.
field-symbols type s_outparams.
* call the procedure which returns the mapping between procedure parameters
* and the generated temporary tables
res_ref = stmt_ref->execute_query( 'CALL zrs_testproc(null) WITH OVERVIEW' ).
clear lt_outparam.
get reference of lt_outparam into lr_outparam.
res_ref->set_param_table( lr_outparam ).
res_ref->next_package( ).
* get the temporary table name for the parameter T1
read table lt_outparam assigning
with key param_name = 'T1'.
assert sy-subrc is initial.
* retrieve the procedure output from the generated temporary table
res_ref = stmt_ref->execute_query( 'SELECT * FROM ' && -temptable_name ).
clear result_tab.
get reference of result_tab into lr_result.
res_ref->set_param_table( lr_result ).
row_cnt = res_ref->next_package( ).
write: / 'EXECUTE WITH GENERATED TEMP TABLES:', / 'Row count:', row_cnt.
perform output_result.
endform.
form handle_sql_exception
using p_sqlerr_ref type ref to cx_sql_exception.
format color col_negative.
if p_sqlerr_ref->db_error = 'X'.
write: / 'SQL error occured:', p_sqlerr_ref->sql_code, "#EC NOTEXT
/ p_sqlerr_ref->sql_message.
else.
write:
/ 'Error from DBI (details in dev-trace):', "#EC NOTEXT
p_sqlerr_ref->internal_error.
endif.
endform.
form output_result.
write / 'Result table:'.
field-symbols type result_t.
loop at result_tab assigning .
write: / -key, -value.
endloop.
endform.
输出:
EXECUTE WITH TRANSFER TABLE:
Row count: 1
Result table:
1 Test value
EXECUTE WITH GENERATED TEMP TABLES:
Row count: 1
Result table_
1 Test value