使用OData服务管理多表插入

2020-08-21 16:45发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


大家好,

我想了解如何使用odata服务管理多表插入。

问题:

例如,我有两个表:

1。 客户(客户ID为主键)

2。 订单(订单ID为主键,客户ID为外键)

客户表具有一对多关系的订单表。

我想创建OData服务,在这里我可以管理插入/更新/删除事务。

我几乎不知道可以使用"关联"来联接表,但是我不确定以下几点:

1。 "协会"是否支持CRUD操作?

2。 如何管理Customer_ID和Order_ID的自动生成的主键创建?

请咨询。

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


大家好,

我想了解如何使用odata服务管理多表插入。

问题:

例如,我有两个表:

1。 客户(客户ID为主键)

2。 订单(订单ID为主键,客户ID为外键)

客户表具有一对多关系的订单表。

我想创建OData服务,在这里我可以管理插入/更新/删除事务。

我几乎不知道可以使用"关联"来联接表,但是我不确定以下几点:

1。 "协会"是否支持CRUD操作?

2。 如何管理Customer_ID和Order_ID的自动生成的主键创建?

请咨询。

付费偷看设置
发送
4条回答
闻人可可
1楼-- · 2020-08-21 17:04

是,CRUD操作支持关联。 您应该使用批处理操作将父/子/关联链接记录全部插入一批。 您使用content-id($,然后是content-id值)作为父/子记录中自动生成的主键的占位符。

不幸的是,您不能将UI5 OData模型用于content-id批处理操作。 您必须手动编码请求正文。 这是即将在10月启动的即将进行的HANA开发的"下一步" openSAP课程的一个示例。

XSODATA服务定义:

 服务{
  
  " sap.hana.democontent.epmNext.data::EPM.MasterData.BusinessPartner"
   作为"业务合作伙伴"
   导航(" ToAddresses"为" AddRef")
    创建事件(在" sap.hana.democontent.epmNext.services:businessPartnersAddresses.xsjslib::bp_create_before_exit"之前);

  " sap.hana.democontent.epmNext.data::EPM.MasterData.Addresses"
   作为"地址"
   创建事件(在" sap.hana.democontent.epmNext.services:businessPartnersAddresses.xsjslib::address_create_before_exit"之前);

  关联" ToAddresses"主体" BusinessPartners"(" ADDRESSES.ADDRESSID")
    多重性" 1"
    从属"地址"(" ADDRESSID")多重性" 1"
    在" sap.hana.democontent.epmNext.data::EPM.MasterData.Addresses"上
            委托人(" ADDRESSID")相关(" ADDRESSID")
            使用" sap.hana.democontent.epmNext.services:businessPartnersAddresses.xsjslib::assocation_create_exit"更新;
 }
 

XSJS退出逻辑:

 $ .import(" sap.hana.democontent.epmNext.services","会话");
 var SESSIONINFO = $ .sap.hana.democontent.epmNext.services.session;


/**
 @param {connection}连接-OData请求中使用的SQL连接
 @param {beforeTableName}字符串-临时表的名称,该表在操作前具有单个条目(仅UPDATE和DELETE事件)
 @param {afterTableName}字符串-操作后带有单个条目的临时表的名称(仅CREATE和UPDATE事件)
  */


 函数bp_create_before_exit(param){


   让之后= param.afterTableName;
   var pStmt;
   尝试{


   pStmt = param.connection.prepareStatement('从虚拟对象中选择" sap.hana.democontent.epmNext.data::businessPartnerId".NEXTVAL);
   var rs = pStmt.executeQuery();
   var PartnerId ='';
   而(rs.next()){
   PartnerId = rs.getString(1);
   }
   pStmt.close();


   pStmt = param.connection.prepareStatement('update"'+之后
   +'"设置PARTNERID =?,'+
    'PARTNERROLE =?,'+
    '" HISTORY.CREATEDBY.EMPLOYEEID" =?,'+
    '" HISTORY.CHANGEDBY.EMPLOYEEID" =?,'+
    '" HISTORY.CREATEDAT" = now(),'+
    '" HISTORY.CHANGEDAT" = now(),'+
    '" CURRENCY" =?');
   pStmt.setString(1,PartnerId);
   pStmt.setString(2,'01');
   pStmt.setString(3,'0000000033');
   pStmt.setString(4,'0000000033');
   pStmt.setString(5,'EUR');

   pStmt.execute();
   pStmt.close();



   }
   抓住(e){


   }


 }


 函数address_create_before_exit(param){


   让之后= param.afterTableName;

   var pStmt;
   尝试{

   pStmt = param.connection.prepareStatement('从虚拟对象中选择" sap.hana.democontent.epmNext.data::addressId".NEXTVAL');
   var rs = pStmt.executeQuery();
   var AddressId ='';
   而(rs.next()){
   AddressId = rs.getString(1);
   }
   pStmt.close();


   pStmt = param.connection.prepareStatement('update"'+之后
   +'"设置" ADDRESSID" =?,'+
    'ADDRESSTYPE =?,'+
    '" VALIDITY.STARTDATE" = TO_DATE('+"'2000-01-01','YYYY-MM-DD')," +
    '" VALIDITY.ENDDATE" = TO_DATE('+"'9999-12-31','YYYY-MM-DD')");
   pStmt.setString(1,AddressId);
   pStmt.setString(2,'02');
   pStmt.execute();
   pStmt.close();

   }
   抓住(e){


   }


 }


/**
 @param {connection}连接-OData请求中使用的SQL连接
 @param {principalTableName}字符串-实体类型在关联的主体端的临时表的名称
 @param {dependentTableName}字符串-具有从属实体类型的临时表的名称
  */




 函数assocation_create_exit(param){
   让princ = param.principalTableName;
   让dep = param.dependentTableName;




   var pStmt = param.connection.prepareStatement('select * from"'+ princ +'"');
   var Principal = SESSIONINFO.recordSetToJSON(pStmt.executeQuery(),'Details');
   pStmt.close();

   var pStmt = param.connection.prepareStatement('select * from"'+ dep +'"');
   var Dependent = SESSIONINFO.recordSetToJSON(pStmt.executeQuery(),'Details');
   pStmt.close();

   $ .trace.debug(JSON.stringify(Principal));
   $ .trace.debug(JSON.stringify(Dependent));
   var pStmt = param.connection.prepareStatement('update" SAP_HANA_EPM_NEXT"。" sap.hana.democontent.epmNext.data::EPM.MasterData.BusinessPartner"'+
      'SET" ADDRESSES.ADDRESSID" =吗?  " PARTNERID"在哪里=?  ');
   pStmt.setString(1,Dependent.Details [0] .ADDRESSID);
   pStmt.setString(2,Principal.Details [0] .PARTNERID);
   pStmt.execute();
   pStmt.close();

 }
 

以及用于构建请求的UI5控制器事件逻辑:

 callCreateServiceBackup:function(){




 var oModel = sap.ui.getCore()。byId(" idodataDeep")。getController()。oModel;
 var oBusinessPartner = {};
 oBusinessPartner.PARTNERID =" 0000000000";
 oBusinessPartner.EMAILADDRESS = sap.ui.getCore()。byId(" email")。getValue();
 oBusinessPartner.COMPANYNAME = sap.ui.getCore()。byId(" CompanyName")。getValue();


 var oAddress = {};
 oAddress.ADDRESSID =" 0000000000";
 oAddress.CITY = sap.ui.getCore()。byId(" City")。getValue();


 var oLink = {};
 oLink.uri =" $ 2";


  var xhr = new XMLHttpRequest();

  xhr.open(" POST",'/sap/hana/democontent/epmNext/services/businessPartnersAddresses.xsodata/$batch',true);

  var token = getCSRFToken();
      xhr.setRequestHeader(" X-CSRF-Token",令牌);

  xhr.setRequestHeader(" Accept",'application/json');
  xhr.setRequestHeader(" Content-Type",'multipart/mixed; boundary = batch');
  xhr.setRequestHeader(" DataServiceVersion",'2.0');
  xhr.setRequestHeader(" MaxDataServiceVersion",'2.0');

  var body ='';

  正文+ ='--batch'+'\ n';
      正文+ ="内容类型:多部分/混合;边界=更改集" +" \ n";
      正文+ ='Content-Transfer-Encoding:binary'+'\ n';
      正文+ ='\ n';
     
      正文+ ='--changeset'+'\ n';
      正文+ ='Content-Type:application/http'+'\ n';
  正文+ ='Content-Transfer-Encoding:binary \ n';
  正文+ ='Content-ID:1 \ n';
      正文+ ='\ n';
     
  正文+ ='POST BusinessPartners HTTP/1.1 \ n';
  正文+ ="内容类型:application/json \ n";
  var jsonBP = JSON.stringify(oBusinessPartner);
  正文+ =" Content-Length:" + jsonBP.length +'\ n';
      正文+ ='\ n';
  正文+ = jsonBP +'\ n';
      正文+ ='--changeset'+'\ n';

      正文+ ='Content-Type:application/http'+'\ n';
  正文+ ='Content-Transfer-Encoding:binary \ n';
  正文+ ='Content-ID:2 \ n';
      正文+ ='\ n';

  正文+ ='POST地址HTTP/1.1 \ n';
  正文+ =" Content-Type:application/json \ n";
  var jsonAdd = JSON.stringify(oAddress);
  正文+ =" Content-Length:" + jsonAdd.length +'\ n';
      正文+ ='\ n';

  正文+ = jsonAdd +'\ n';
      正文+ ='--changeset'+'\ n';

      正文+ ='Content-Type:application/http'+'\ n';
  正文+ ='Content-Transfer-Encoding:binary \ n';
      正文+ ='\ n';
     
  正文+ ='PUT $ 1/$ links/AddRef HTTP/1.1 \ n';
  正文+ =" Content-Type:application/json \ n";
  var jsonLink = JSON.stringify(oLink);
  正文+ =" Content-Length:" + jsonLink.length +'\ n';
      正文+ ='\ n';
     
  正文+ = jsonLink +'\ n';

      正文+ ='--changeset'+'-\ n';
      正文+ ='\ n';
    
  正文+ ='--batch'+'-\ n';
     
          xhr.onload = function(){}
  xhr.send(body);
  警报("已创建业务伙伴");




 }
 
小c菟菟
2楼-- · 2020-08-21 17:09

Sanjoy Saha -我5年前的回答没事做 与UI5中的odata模型。 我真的建议您在适当的UI5标签中提出这个新问题。

软件心理学工程师
3楼-- · 2020-08-21 17:13

此消息已被审核。

三十六小时_GS
4楼-- · 2020-08-21 17:11

嗨,斯里哈里,

1)=== >>>不可能进行多表CRUD操作,但是我们可以对UI5进行读操作,并且可以使用NAVIGATE和ASSOCIATION ........ i创建多个表。 被引用用于CRUD操作的许多块但没有解决方案,因此我决定并创建了一个用于CREATE/UPDATE过程的过程。给定的过程同时执行CREATE和UPDATE

我在ODATA中对其操作进行了测试,但其工作状况良好,但条件应基于主键和相关的业务逻辑。

2)ODATA服务的创建/更新过程?????

Pr_Create_Update过程

步骤" shema"。" folder.subfolder.procedures :: prcedurename_create_update"(

在"您想要的目录表"行中,

OUT错误"错误消息的表类型::错误")

语言SQLSCRIPT

SQL安全调用程序

默认模式"模式名称"

AS

开始

/*****************************

说明:该过程将从OData调用到

从用户界面更新主车辆详细信息

*****************************/

DECLARE i_a NVARCHAR(20);

DECLARE i_b NVARCHAR(20);

DECLARE i_c NVARCHAR(30);

DECLARE i_d NVARCHAR(3);

DECLARE i_e NVARCHAR(3);

DECLARE I_f NVARCHAR(3);

DECLARE i_a_COUNT个nvarchar;

DECLARE i_b_COUNT个nvarchar;

SQLEXCEPTION的DECLARE退出处理程序

开始

错误=选择:: SQL_ERROR_CODE作为http_status_code,

:: SQL_ERROR_MESSAGE作为error_message,

" SQL EXCEPTION"作为虚拟对象的详细信息;

END;

选择a,b,c,d,e,f到i_a,i_b,i_c,i_d,i_e,i_f FROM:row;

从"表名"中将count(*)选择为i_a_COUNT,其中a =:i_a;

从"表名"中将count(*)选择到i_b_COUNT中,其中b =:i_b;

if(((:i_a_COUNT = 0 and:I_b_COUNT> 0)或((:I_a_COUNT> 0 and:I_b_COUNT = 0))然后

错误=选择500作为http_status_code,

"无效输入"作为error_message,

"无效的数字/b数字"作为哑元的详细信息;

elseif(:I_a_COUNT = 0和:I_b_COUNT = 0)然后

插入"表名"

(" a"," b"," c"," d"," e"," f")值

(I_a,i_b,i_c,i_d,i_e,i_f);

elseif(:I_a_count> 0和:I_b_COUNT> 0)然后

更新"模式名称"。" folder.subfolder ::表名称" SET" a" =:i_a,i_b,i_c,i_d,i_e,i_f其中a =:I_a AND b =:I_b;

如果结束;

END;



感谢和问候,

SUNNY

一周热门 更多>