SAP CDS view自学教程之九:cube view和query view的实现原理
时间:2022-07-23
本文章向大家介绍SAP CDS view自学教程之九:cube view和query view的实现原理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
In previous eight steps all we focus on is transactional stuff. This time let’s touch some analytics stuff.
Let’s first create a most simple database table in ABAP backend:
Then create a simple cube view:
@EndUserText.label: 'Jerry cube view'
@Analytics.dataCategory: #CUBE
@VDM.viewType: #COMPOSITE
@AccessControl.authorizationCheck:#CHECK
@AbapCatalog.sqlViewName: 'zprdcube'
define view Z_C_Prod_Cube as select from zprd_query{
key zprd_query.prod_id,
zprd_query.prod_text,
@DefaultAggregation: #MAX
zprd_query.quantity
}
This cube view has only three fields: prod_id, prod_text and quantity.
For more detail for annotation @Analytics.dataCategory: #CUBE, please refer to SAP help.
Then create a query view on top of the cube view:
@EndUserText.label: 'Jerry query verification'
@VDM.viewType: #CONSUMPTION
@Analytics.query: true
@AccessControl.authorizationCheck:#NOT_ALLOWED
@AbapCatalog.sqlViewName: 'zprdquery'
@OData.publish: true
define view Z_C_Product as select from Z_C_Prod_Cube {
key Z_C_Prod_Cube.prod_id,
Z_C_Prod_Cube.prod_text,
@DefaultAggregation: #MAX
Z_C_Prod_Cube.quantity
}
Since I use @OData.publish: true, a new OData service is automatically generated when this query view is activated.
We have already discussed how this generation is achieved in this blog:My CDS view self study tutorial – Part 4 how does annotation @OData.publish work.
Once activation is finished, we can do some testing. In ABAP backend I have two entries in the table:
So once we perform the read operation via generated OData service: /sap/opu/odata/sap/Z_C_Product_cds/Z_C_PRODUCT
we can see these two entries are returned in OData response automatically:
Let’s do some further research to find out how these two entries are retrieved from backend.
We have CDS view name as Z_C_Product and the generated OData service based on it has name Z_C_Product_CDS.
Like normal CDS view activation with annotation @OData.publish: true, there is also a new ABAP class @OData.publish: true automatically generated, which has only one method redefined: GET_QUERY_NAME. In this method, a constant attribute is returned.
The content of this attribute: ‘2Czprdquery’.
The biggest difference compared with a normal CDS view activation is: when a query view is activated, the generated OData service data provider class has CL_NAT_ODATA_MODEL_ABS as its super class, giving you a hint that all data retrieved based on this query view will be handled by analytics framework.
While for a normal CDS view, the DPC class has super class CL_SADL_GTK_EXPOSURE_MPC, which means the data access in this case is done by SADL framework.
In order to figure out the detail data access logic implementation by analytics framework, I write the following report to simulate the OData call:
REPORT zcds_get_query_view_data.
DATA(lo_tool) = NEW cl_nat_generic_dpc( ).
DATA(lo_context) = NEW /iwbep/cl_mgw_context( ).
DATA: l_r_rs_gw_columns TYPE REF TO cl_abap_tabledescr,
l_t_rs_gw_columns TYPE REF TO data,
lo_request TYPE REF TO /iwbep/cl_mgw_request,
lo_detail TYPE REF TO /iwbep/if_mgw_core_srv_runtime=>ty_s_mgw_request_context,
ls_detail TYPE /iwbep/if_mgw_core_srv_runtime=>ty_s_mgw_request_context,
lt_header TYPE tihttpnvp,
lt_filter TYPE /iwbep/t_mgw_select_option,
lt_order TYPE /iwbep/t_mgw_sorting_order,
ls_page TYPE /iwbep/s_mgw_paging,
ls_header TYPE LINE OF tihttpnvp.
FIELD-SYMBOLS:
<l_t_rs_gw> TYPE table.
lo_context->/iwbep/if_mgw_context~set_parameter( iv_name = /iwbep/if_mgw_context=>gc_param_isn
iv_value = 'Z_C_PRODUCT_CDS' ).
lo_context->/iwbep/if_mgw_context~set_parameter( iv_name = /iwbep/if_mgw_context=>gc_param_isv
iv_value = '0001' ).
lo_tool->/iwbep/if_mgw_core_srv_runtime~set_context( lo_context ).
CREATE DATA lo_detail.
lo_request = NEW /iwbep/cl_mgw_request( ir_request_details = lo_detail it_headers = lt_header ).
DATA(lo_rt) = NEW cl_eq_bics_gw_rt( i_query = '2Czprdquery'
i_servicetype_oq = abap_true ).
lo_rt->get_designtime(
IMPORTING
e_t_column_description = DATA(l_t_query_struc) ) .
l_r_rs_gw_columns = cl_eq_bics_gw_dt=>build_rs_structure( l_t_query_struc ).
CREATE DATA l_t_rs_gw_columns TYPE HANDLE l_r_rs_gw_columns.
ASSIGN l_t_rs_gw_columns->* TO <l_t_rs_gw>.
ls_detail-technical_request-service_name = 'Z_C_PRODUCT_CDS'.
ls_detail-technical_request-service_version = '0001'.
ls_detail-technical_request-source_entity_type = ls_detail-technical_request-target_entity_type
= 'Z_C_PRODUCTType'.
ls_detail-technical_request-source_entity_set = ls_detail-technical_request-target_entity_set
= 'Z_C_PRODUCTTypeCollection'.
ls_header-name = 'dummy'.
APPEND ls_header TO ls_detail-technical_request-request_header.
CALL METHOD lo_tool->/iwbep/if_mgw_core_srv_runtime~read_entityset(
EXPORTING
iv_entity_name = 'Z_C_PRODUCTType'
iv_source_name = 'Z_C_PRODUCTType'
is_paging = ls_page
it_order = lt_order
it_filter_select_options = lt_filter
is_request_details = ls_detail
CHANGING
cr_entityset = l_t_rs_gw_columns
ct_headers = lt_header
).
ASSIGN l_t_rs_gw_columns->* TO <l_t_rs_gw>.
WRITE: 'lines of data: ', lines( <l_t_rs_gw> ).
With SAT trace I can easily locate the exact location of code where the data retrieve is done:
In this line the DB cursor is opened with generated SQL statement:
Mystery Revealed!
- R语言的kmeans客户细分模型聚类
- .NET的资源并不限于.resx文件,你可以采用任意存储形式[下篇]
- 量化投资教程:用R语言打造量化分析平台
- 也谈事件(Event)
- Zuul:构建高可用网关之多维度限流
- Hystrix:HystrixCollapser请求合并
- oauth2.0 实现spring cloud nosession
- 基于自定义向导的C++单元测试环境自动化配置
- 【spring cloud】自定义jwt实现spring cloud nosession
- R语言的三种聚类方法
- ArrayList foreach 循环里进行元素的 remove add 操作有什么现象?
- 10个令人相见恨晚的R语言包
- 小心Windows旧版认证暴露你的系统帐户密码
- DNS Shell初体验
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一文了解JDK12 13 14 GC调优秘籍-附PDF下载
- JVM系列之:String.intern和stringTable
- 5万字长文:Stream和Lambda表达式最佳实践-附PDF下载
- 实现浏览器中的最大请求并发数控制
- 【漏洞复现】Weblogic漏洞搭建与复现:CVE-2018-2894 任意文件上传
- 终于把进程和线程学会了
- 对方向你转账60元--三角函数方法精确位的实现
- 牛客网-树的子结构
- 牛客网-删除链表中重复的节点
- 牛客网-包含min函数的栈
- 牛客网-反转链表
- 牛客网-替换空格
- 手把手教你破解文件密码、wifi密码、网页密码
- 如何安装 Elastic 栈中的 Logstash
- 你的GitHub项目被封存到北极了吗?