ADBC 查询语法介绍:EXECUTE_QUERY

可使用 CL_SQL_STATEMENT 类的以下实例方法执行查询:

  • EXECUTE_QUERY

该方法有一个字符串类型的强制输入参数 STATEMENT,必须向其传递语法正确的 SELECT 语句。与 DML 语句一样,SET_PARAM 方法可用于将 ABAP 数据对象绑定到占位符。

查询结果将在返回值 RESULT_SET 中返回对 CL_SQL_RESULT_SET 类对象的引用。该对象的方法允许访问查询的结果集。为了在数据库 LUW 结束后保留结果集,可以在 EXECUTE_QUERY 方法的输入参数 HOLD_CURSOR 中填入 X。

结果对象的 CL_SQL_RESULT_SET 类提供了以下用于将结果集读入 ABAP 数据对象的实例方法,

SET_PARAM, NEXT, 和 CLOSE

这三个方法可访问结果集中的单个行和列

  • SET_PARAM:使用 SET_PARAM,必须通过向该方法传递每列的相应数据引用,从左到右为列分配兼容的 ABAP 数据对象。
  • NEXTNEXT 用于逐个寻址结果集中的行。如果可以寻址该行,则返回值为 1,否则为 0。
  • CLOSE
    使用 CLOSE 关闭读取。如果要修改两次调用 NEXT 之间的参数绑定,必须先调用 CLEAR_PARAMETERS 方法。

SET_PARAM_STRUCT、NEXT 和 CLOSE

这些方法提供了对结果集中各行的访问。

使用 SET_PARAM_STRUCT 方法,必须通过向方法传递相应的数据引用,为结果集的行分配完全兼容的 ABAP 结构。可以将指定要读取的列的名称和顺序的内部表传递给参数 CORRESPONDING_FIELDS。其余方法与 SET_PARAM 方法相同。

SET_PARAM_TABLE、NEXT_PACKAGE 和 CLOSE

这些方法可以访问结果集中的多行

使用 SET_PARAM_TABLE,必须通过向该方法传递相应的数据引用,为结果集的行分配一个结构完全兼容的内部表。与 SET_PARAM_STRUCT 一样,CORRESPONDING_FIELDS 参数用于指定要传送的列。

这里使用 NEXT_PACKAGE 代替 NEXT,最多读取传递给输入参数 UPTO 的行数。如果没有向 UPTO 传递任何值,则会读取所有行。在每次调用 NEXT_PACKAGE 时,读取的记录都会追加到内部表中,不会删除之前的内容,读取的记录数会在返回值 ROWS_RET 中返回。在更改参数绑定和 CLOSE 时,情况与 SET_PARAM 相同。

如果查询返回一个以上的结果集,上述方法默认访问第一个结果集,NEXT_RESULT_SET 方法可用于切换到下一个结果集。对于每个结果集,必须再次使用上述 SET_... 方法才能附加数据到 ABAP 数据对象。

提示

  • 可以将 ABAP 字典中内置类型为 INT2 的指示变量的数据引用传递给 SET_PARAM 方法的可选输入参数 IND_REF。在该数据引用中,值 -1 表示数据库中是否存在空值。
  • 出于安全考虑,最好使用占位符 ? 来设置查询参数,而不是连接动态内容。这也是防止 SQL 注入的一种方法。如果语句只包含程序中的静态内容,而程序外的动态内容只能在操作符位置使用占位符,并且语句不能从外部修改。
  • 在数据库表中的字段和 ABAP 数据对象之间进行赋值时,ABAP 类型和数据库类型之间会发生映射。ABAP 类型应与数据库类型相匹配。如果不匹配,则必须在本地 SQL 接口中进行转换。这些转换与平台有关,并可能引发异常。
  • EXECUTE_QUERY 方法也可用于调用存储过程。在符合要求的数据库中,内部表等可以绑定到结果集。EXECUTE PROCEDURE 方法则无法做到这一点(请参阅该方法下的示例)。
  • 通用方法 EXECUTE 也有一个 CL_SQL_RESULT_SET 类型的返回值,其使用方法与 EXECUTE_QUERY 相同。
  • 在调用具有多个输出参数的数据库存储过程时,可能会出现多个结果。

示例 1:读取数据到工作区

使用 ADBC 从之前使用 ABAP SQL 填充的数据库表中按顺序读取行到工作区。

ABAP 复制代码
DELETE FROM demo_update.
INSERT demo_update FROM TABLE @(
  VALUE #( ( id = 'X' col1 = 1 col2 = 2 col3 = 3 col4 = 4 )
           ( id = 'Y' col1 = 5 col2 = 6 col3 = 7 col4 = 8 ) ) ).

DATA result TYPE demo_update.
TRY.
    FINAL(query) = NEW cl_sql_statement( )->execute_query(
       `SELECT client, id, col1, col2, col3, col4 ` &&
       `       FROM demo_update ` &&
       `       WHERE client = '` && sy-mandt && `' `  ).
    query->set_param_struct( struct_ref = REF #( result ) ).
    WHILE query->next( ) > 0.
      cl_demo_output=>write( result ).
    ENDWHILE.
    query->close( ).
  CATCH cx_sql_exception INTO FINAL(exc).
    cl_demo_output=>display( exc->get_text( ) ).
    RETURN.
ENDTRY.

cl_demo_output=>display( ).

示例2:读取数据到内表

ABAP 复制代码
DELETE FROM demo_update.
INSERT demo_update FROM TABLE @(
  VALUE #( ( id = 'X' col1 = 1 col2 = 2 col3 = 3 col4 = 4 )
           ( id = 'Y' col1 = 5 col2 = 6 col3 = 7 col4 = 8 ) ) ).

DATA result TYPE TABLE OF demo_update WITH EMPTY KEY.
TRY.
    FINAL(query) = NEW cl_sql_statement( )->execute_query(
       `SELECT client, id, col1, col2, col3, col4 ` &&
       `       FROM demo_update ` &&
       `       WHERE client = '` && sy-mandt && `' `  ).
    query->set_param_table( itab_ref = REF #( result ) ).
    query->next_package( ).
    query->close( ).
  CATCH cx_sql_exception INTO FINAL(exc).
    cl_demo_output=>display( exc->get_text( ) ).
    RETURN.
ENDTRY.

cl_demo_output=>display( result )

还有三个官方可以执行的 Demo,通过 SE38 运行下列程序:

  • DEMO_ADBC_QUERY:ADBC 查询示例,类 CL_SQL_STATEMENT 中的 EXECUTE_QUERY 方法用于读取当前客户端的数据库表 SFLIGHT 中的三列。使用 CL_SQL_RESULT_SET 类中的 SET_PARAM_TABLE 方法将一个适当的内部表绑定到结果集中。使用 NEXT_PACKAGE 方法将结果集中的所有行传送到内部表。
  • DEMO_ADBC_DDL_DML:该程序可创建一个数据库表,其名称可由用户选择。之后,可以向数据库表中插入 100 条记录,读取单个记录,并再次删除数据库表。本地 SQL 语句使用字符串表达式传递给 CL_SQL_STATEMENT 类的方法。
  • DEMO_ADBC_DDL_DML_BULK_ACCESS:该程序可创建和删除数据库表,表名可由用户选择。可以向数据库表中插入行、再次删除行、读取所有行并再次删除数据库表在 DML 语句的所有方法中,参数都使用内部表绑定。
    • 插入(insert)会将内部表中的所有行写入数据库表中,而该表的键值尚未存在。
    • 删除(delete)数据库表中键值出现在内部表中的所有记录。
    • 查询(select )将数据库表中所有行的查询结果集读入内部表。

参考文档:

相关推荐
m0_748256568 分钟前
Rust环境安装配置
开发语言·后端·rust
程序猿阿伟10 分钟前
《C++巧铸随机森林:开启智能决策新境界》
开发语言·c++·随机森林
O(1)的boot16 分钟前
微服务的问题
java·数据库·微服务
一个略懂代码的程序员19 分钟前
Redis01
java·redis
IT界的奇葩23 分钟前
基于springboot使用Caffeine
java·spring boot·后端·caffeine
假意诗人32 分钟前
【NextJS】Arco Design与Next.js快速上手
开发语言·javascript·arco design
智慧源点33 分钟前
阿里云负载均衡SLB实践
服务器·阿里云·负载均衡
西埃斯迪恩-霖34 分钟前
Idea导入SpringBoot3.2.x源码
java·ide·intellij-idea
凡人的AI工具箱36 分钟前
40分钟学 Go 语言高并发教程目录
开发语言·后端·微服务·性能优化·golang
pzx_00137 分钟前
【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究
开发语言·论文阅读·python·算法·leetcode·sklearn