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
1698818722138.png
测试连接如果出错,可以用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.