点击此处---> 群内免费提供SAP练习系统(在群公告中)
加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)
报错及处理一 可能的报错及处理方式 下图报错的原因是访问ORACLE数据库必须指定一个SCHEMA. 这个可以配置在连接参数中. 报错及处理二 出现下面的报错,表示系统尝试使用MANDT限制数据, 此时需要给OPEN SQL 语句添加CLIENT SPECIFIED 强制OPEN SQL 不要补充MANDT限制 读取多条记录的方式 游标方式 图一 非游标方式 图二 非游标方式其实隐式使用了游标.性能比游标方式要差.数据量小的时候看不出来. 大量数据读取就能看出二者的性能差异了. 图三是标准帮助中提示的优劣比较. 图一 图二 图三 图四 图五 图六 约定 如果你对这篇文章感兴趣,请帮忙点赞,在看,分享. (如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程. 越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.) 公众号 : syjf1976_abap ABAP开发技巧 微信号 : 392077 请微信联系管理员: syjf1976 sharry_xlp Yannick_Duan 申请进入公众号讨论群 示例代码,OPEN SQL: 示例代码 NATIVESQL 示例代码 ADBC*&---------------------------------------------------------------------*
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 SPECIFIED 避免CLIENT不同干扰数据获取
SELECT * FROM usr02 CLIENT SPECIFIED INTO TABLE @DATA(lt_usr02) BYPASSING BUFFER CONNECTION R/3*S4Q
WHERE bname = '00177'.
."可以获取数据
sy-subrc . =
cl_demo_output=>write( lv_subrc ).
cl_demo_output=>write( lt_usr02 ).
cl_demo_output=>display( ).
WHEN p_ora.
*访问另一个其它系统的同名表
, 目标表没有, 则需要添加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. "在连接中提交.
*&---------------------------------------------------------------------*
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.
'SELECT方式一:DO循环读取游标,添加内表'. =
'SELECT方式二:通过例程添加内表'. =
'UPDATE:更新表内容'. =
'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.
通过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 字段必须与结构字段顺序一致,且字段长度一致.
FETCH NEXT dbcur INTO :ls_TEMP
DO.
EXEC SQL.
FETCH NEXT dbcur INTO :ls_TEMP-ZZTNO,:LS_TEMP-WERKS
ENDEXEC.
IF sy-subrc <> 0.
EXIT.
ELSE.
APPEND ls_temp TO lt_temp.
ENDIF.
ENDDO.
"关闭游标
EXEC SQL.
CLOSE dbcur
ENDEXEC.
lt_temp[]. =
ENDFORM.
*&---------------------------------------------------------------------*
Form FRM_METHOD_2
*&---------------------------------------------------------------------*
text
*&---------------------------------------------------------------------*
--> p1 text
<-- p2 text
*&---------------------------------------------------------------------*
FORM frm_method_2 .
conn = 'MTD'.
"检查连接是否已经打开
EXEC SQL.
SET CONNECTION :conn
ENDEXEC.
IF sy-subrc <> 0. "如果连接没有打开, 打开连接
EXEC SQL.
CONNECT TO :conn
ENDEXEC.
ENDIF.
工作区 gs_temp 内表 gt_temp 必须是全局变量 :
EXEC SQL PERFORMING FRM_FILL_DATA.
SELECT zztno,werks FROM zttemp INTO :GS_TEMP
ENDEXEC.
ENDFORM.
FORM frm_fill_data.
APPEND gs_temp TO gt_temp.
ENDFORM.
*&---------------------------------------------------------------------*
Form FRM_UPDATE
*&---------------------------------------------------------------------*
text
*&---------------------------------------------------------------------*
--> p1 text
<-- p2 text
*&---------------------------------------------------------------------*
FORM frm_update .
DATA: lv_werks(4).
lv_werks = '1002'.
EXEC SQL.
UPDATE ZTTEMP SET WERKS = :LV_WERKS
WHERE WERKS = '1003'
ENDEXEC.
IF sy-subrc = 0.
*提交数据更新
EXEC SQL.
COMMIT WORK
ENDEXEC.
DATA: lv_msg(50).
lv_msg = '更新成功记录数:' && sy-dbcnt .
cl_demo_output=>display( lv_msg ).
ELSE.
cl_demo_output=>display( '更新失败' ).
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
Form FRM_INSERT
*&---------------------------------------------------------------------*
text
*&---------------------------------------------------------------------*
--> p1 text
<-- p2 text
*&---------------------------------------------------------------------*
FORM frm_insert .
DATA: lv_werks(4).
lv_werks = '1002'.
EXEC SQL.
INSERT INTO ZTTEMP VALUES ('4502',:LV_WERKS)
ENDEXEC.
IF sy-subrc = 0.
*提交数据更新
EXEC SQL.
COMMIT WORK
ENDEXEC.
DATA: lv_msg(50).
lv_msg = '写入成功记录数:' && sy-dbcnt .
cl_demo_output=>display( lv_msg ).
ELSE.
cl_demo_output=>display( '写入失败' ).
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
Report ZTS_DBCO_ADBC
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zts_dbco_adbc.
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.
DATA: gv_sql TYPE string.
START-OF-SELECTION.
gv_sql = 'SELECT zztno,werks FROM zttemp'.
PERFORM frm_get_data_adbc_simple.
PERFORM frm_get_data_adbc.
cl_demo_output=>display( gt_temp ).
*&---------------------------------------------------------------------*
Form FRM_GET_DATA_ADBC
*&---------------------------------------------------------------------*
text
*&---------------------------------------------------------------------*
--> p1 text
<-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data_adbc .
DATA: r_adbc_conn TYPE REF TO cl_sql_connection,
r_adbc_query TYPE REF TO cl_sql_statement,
r_metadata TYPE REF TO data,
it_metadata TYPE adbc_rs_metadata_descr_tab,
lv_len TYPE i,
lv_off TYPE i,
wa_metadata LIKE LINE OF it_metadata,
r_adbc_result TYPE REF TO cl_sql_result_set,
r_tabletype TYPE REF TO cl_abap_tabledescr,
r_cxadbc TYPE REF TO cx_dba_adbc,
r_cxsql TYPE REF TO cx_sql_exception,
TYPE n,
column_names TYPE HASHED TABLE OF adbc_name WITH UNIQUE KEY table_line.
DATA: lv_stmt_type TYPE string.
DATA:
ex_structdescr TYPE REF TO cl_abap_structdescr,
ex_result_ref TYPE REF TO data.
*获取sql语句的类型
lv_stmt_type = cl_hdb_sql_executor=>get_statement_type( gv_sql ).
*创建默认数据库的链接对象
r_adbc_conn = cl_db6_con=>get_connection( 'MTD' ).
*创建一个查询对象
r_adbc_query = r_adbc_conn->create_statement( ).
*基于sql语句创建一个结果对象
r_adbc_result = r_adbc_query->execute_query( gv_sql ).
*获取结果集合的字段名
it_metadata = r_adbc_result->get_metadata( ).
*使用结果集合的字段信息,创建一个数据对象-结构
r_metadata = r_adbc_result->get_struct_ref( md_tab = it_metadata p_strict = abap_false ).
*创建一个数据对象-内表
ex_structdescr ?= cl_abap_typedescr=>describe_by_data_ref( r_metadata ).
r_tabletype = cl_abap_tabledescr=>create( p_line_type = ex_structdescr
p_table_kind = cl_abap_tabledescr=>tablekind_std ).
CREATE DATA ex_result_ref TYPE HANDLE r_tabletype.
*传递结果集一个数据对象-内表
itab_ref = ex_result_ref ).
*获取数据内容
EXPORTING upto = 100 ).
*关闭连接
).
*赋值数据到内表
ASSIGN ex_result_ref->* TO
ENDFORM.
FORM frm_get_data_adbc_simple .
DATA: r_adbc_conn TYPE REF TO cl_sql_connection,
r_adbc_query TYPE REF TO cl_sql_statement,
r_metadata TYPE REF TO data,
it_metadata TYPE adbc_rs_metadata_descr_tab,
lv_len TYPE i,
lv_off TYPE i,
wa_metadata LIKE LINE OF it_metadata,
r_adbc_result TYPE REF TO cl_sql_result_set,
r_tabletype TYPE REF TO cl_abap_tabledescr,
r_cxadbc TYPE REF TO cx_dba_adbc,
r_cxsql TYPE REF TO cx_sql_exception,
TYPE n,
column_names TYPE HASHED TABLE OF adbc_name WITH UNIQUE KEY table_line.
DATA: lv_stmt_type TYPE string.
DATA:
ex_structdescr TYPE REF TO cl_abap_structdescr,
ex_result_ref TYPE REF TO data.
*创建默认数据库的链接对象
r_adbc_conn = cl_db6_con=>get_connection( 'MTD' ).
*创建一个查询对象
r_adbc_query = r_adbc_conn->create_statement( ).
*基于sql语句创建一个结果对象
r_adbc_result = r_adbc_query->execute_query( gv_sql ).
*定义
DATA: lr_ref LIKE REF TO gt_temp.
CREATE DATA lr_ref .
*传递结果集一个数据对象-内表
itab_ref = lr_ref ).
*获取数据内容
EXPORTING upto = 100 ).
*关闭连接
).
*赋值数据到内表
gt_temp = lr_ref->*.
ENDFORM.