ABAP 7.50 新特性 – Open SQL中的宿主表达式和其它表达式
在长期的停滞后,Open SQL的发展终于从沉睡中醒来。从ABAP 7.40开始,SAP推进了某些关键的改变,以尽可能地包含SQL92中的特性,并提供与ABAP CDS中的DDL里面的SELECT一样的功能给Open SQL。为了实现这些目标,ABAP运行时环境中引入了一个新的SQL parser作为Open SQL的新基础。结果就是,Open SQL现在可以在ABAP中扮演一些和以往不同的角色了。
虽然在7.40之前,Open SQL更多地被视为ABAP语言本身的一部分,但在同时,SQL关键字变得越来越介词化了。关于这点,主要的体现之一便是有关宿主变量的新规则。在7.40之前,你可以像在其它ABAP语句中使用ABAP变量那样在Open SQL中使用它们。实际上,这种自由阻止了更高效的开发。Open SQL语句在被转换为native SQL之后才会在数据库中运行。为了在WHERE条件中实现比简单比较更为复杂的东西,Open SQL parser必须能清晰的区分运算符两端的东西到底是ABAP变量、还是数据库内容,从而发送相应的内容给数据库。为了完成这一任务,Open SQL中的ABAP变量因此成为了完全的宿主变量(host variables)。就像ABAP变量在native SQL中的成分一样(EXEC SQL)。你可以(而且应当)在Open SQL中的ABAP 宿主变量前加上转义符@。实际上,只有这样做了,你才能使用ABAP 7.40版本之后的全部Open SQL新特性。Open SQL中引入的其它的基础修改也是为了让其更加适应未来,比如逗号分隔、以及将SELECT语句的INTO附加项放在authentic SQL子句的后面。(译注:authentic是什么意思没看懂,不过这句话的意思应当是指INTO语句不应是SQL本身的一部分,所以要放到后面以示区分)
这些方法带来的第一个好处,已经在ABAP 7.40版本中放出,包括可以在不同操作数位置使用的SQL表达式,以及内联声明的可能性。在ABAP 7.50中,Open SQL依然在发展着,本文将介绍一些新特性(未来还会有更多)。
本文链接:http://www.cnblogs.com/hhelibeb/p/7135899.html
原文标题:ABAP News for Release 7.50 – Host and Other Expressions in Open SQL
宿主表达式
在大多数可以放置宿主变量的地方,包含7.40版本以来的SQL表达式的操作数位置或者写SQL语句的工作区,现在可以通过如下方式放置宿主表达式(host expression):
… @( abap_expression ) …
宿主表达式abap_expression可以是任何ABAP表达式,可以是一个构造器表达式、表表达式、算术表达式、字符串表达式、bit表达式、内建函数、函数性的方法、或者是方法,它通过括号()包围起来,并且要加上前缀@。Open SQL中的宿主表达式从左到右计算,并且它们的结果会作为宿主变量传递给数据库。事实上,你可以将宿主表达式视为通过ABAP表达式为ABAP帮助变量赋值的简写。以下例子演示了一个表表达式,表达式从内表carriers中读取值,并放置在where条件右端:
SELECTcarrid, connid, cityfrom, citytoFROMspfliWHERE carrid =@( VALUE spfli-carrid( carriers[ KEY name
carrname= name ]-carrid
OPTIONAL ) )INTO TABLE @DATA(result)
REST Adapter实现SAP PI中的增强XML/JSON格式转换
SAP标准的REST adapter有着XML/JSON转换的功能,它很有用,因为一方面SAP PI/PO内部以XML格式处理数据,而另一方面,在处理REST架构风格的时候,JSON才是事实上的格式。
然而,观察下网上有关REST Adapter的相关问题,可以得出一个结论:XML消息处理后生成的JSON输出并非总是正确的,有时候它会把人引入歧途。SAP积极地增强了REST Adapter的各方面功能——定制化和特性丰富的JSON处理就是其中一个重点领域。许多相关特性已经在记录在SAP Help的文档中。但是其中的一项相当强大、灵活的功能——名为“增强XML/JSON转换”的功能,却只是简单地在SAP Note 2175218中提及。在本文中,我将阐述这个功能的用法,以及提供有效参数化方法的细节。
在内部,REST adapter使用了第三方的Jettison以实现JSON处理。在标准配置中,REST adapter依赖于Jettison处理器默认的转换逻辑,它不会考虑或关联相应的消息类型中定义的有效元素属性,而是有自己的优化和类型机制,该机制基于所要处理的XML文档的元素的值的本来性质,而非消息的XSD schema。这样一来的结果是,有时转换会导致不合需求的输出。以下是两个通常的例子:
- 如果一个XML元素定义为数组,但是在被转换的XML有效数据中只包含一行,Jettison处理器将可能会将其转换为非数组类型。
- 如果一个XML元素定义为字符串,但是在被转换的XML有效数据中只有数字型的值,Jettison处理器将可能会将其转换为整数类型。
在某些情况下,不合适的类型转换对程序而言是不可接受的——这也是增强XML/JSON转换可以帮助我们解决的问题。
SAP Note 2175218介绍了增强XML/JSON转换背后的一个想法,它是有关JSON处理器如何对待特别的XML元素的明确的描述。让我们基于一个练习例子来测验这个功能:
下面是一个消息类型的定义,它用于同步场景的返回消息,我们在其中使用了REST sender channel。如你所见,它包含了多种类型的元素,包含一个数组:
XML格式的示例回复消息是这样的:
使用REST sender channel的标准配置,将上面的XML消息格式化后的JSON相应消息是这样的:
可以注意到,某些元素类型被错误的解释了,比如:
- 元素“ID”没有被视为字符串,而是数字——Jettison处理器将它作为数字对待,因为元素的值只包含数字类型的字符;
- 元素“Properties”没有被视为数组,Jettison处理器将它作为嵌套结构中的非数组对象,因为这个元素只包含“Property”的一个子实体(没有其它兄弟元素)。
让我们通过增强XML/JSON转换来修复它。在REST sender channel中,增强XML/JSON转换的参数化信息存储在表 “Custom XML/JSON Conversion Rules”中。下面是针对之前高亮的有问题的类型和转换不匹配的配置。
在再次执行接口后,检查被格式化为JSON的响应消息,可以观察到,现在产生了正确的JSON输出:
我在官方材料中没有看到有关于参数化的细节,所以让我来总结下增强XML/JSON转换中可以使用的可接受的和有效值,以及有关它们的使用的解释性说明。内容在下表:
字段 |
描述 |
有效值 |
XML 命名空间 |
XML元素的命名空间 |
|
前缀 |
XML元素命名空间前缀 |
|
名称 |
XML元素名 |
|
类型 |
XML元素类型。 以下类型是当前支持的: String, Integer, Decimal, Boolean. 只要它是有效值列表中提到的值之一,就不会区分类型值的符号。 如果没有指定值,不会应用指定的XML/JSON转换指令,而是会执行默认的Jettison处理器逻辑。 |
String type string xs:string xsd:string Integer type int integer xs:integer xsd:integer Decimal type decimal numeric float xs:decimal xsd:decimal Boolean type bool boolean xs:boolean xsd:boolean |
数组类型 |
XML元素是否是数组的指示符。 只要它是有效值列表中提到的值之一,就不会区分类型值的符号。 如果没有指定值,数组指示符默认为false。 |
如果是数组: 1 true yes 如果不是数组: 0 false no |
默认值 |
在XML/JSON转换失败的情况下会赋给JSON元素的值。
例如,在上面给的demo中,元素“Quantity”的值会被作为整数处理。如果原始值不能转换为整数(比如含有字母),JSON输出会得到一个默认值。在该情况下,这个值是“0”。 需要注意的是,对于默认值而言,系统不会针对在“TYPE”中指定的类型进行元素类型检查——它会被当作字符串。在这种方式下,比如,你可以指定默认值“Invalid value”给“Quantity”。系统不会提示错误,无论是在communication channel激活的时候还是REST adapter运行期间处理相关消息的时候,即便默认值和元素类型(整型)完全不匹配。记住这点,应当注意设置默认值时要保持其类型的一致性。 |
Any value. 下面的值有点特别: “null” (带引号) – 被解释为字符串“null” null (无引号) – 被解释为null “” (只有引号 – 被解释为空字符串 |
本文链接:http://www.cnblogs.com/hhelibeb/p/7395567.html
英文原文:REST Adapter in PI/PO: Enhanced XML/JSON Conversion
CDS测试框架介绍:如何为ABAP CDS Entities写测试
动机
现在大家都知道单元测试对我们代码的好处。并且我们都承认它是开发过程中不可或缺的一部分。但是在把代码切换到数据库的模式下的时候,我们被粗暴地打回了软件测试的黑暗年代...我们现在面临着逻辑下推到ABAP CDS entities后,代码要如何测试的难题。
CDS Test Double Framework允许开发者们通过众所周知的ABAP Unit Test Framework自动化地测试CDS entities。
本文链接:http://www.cnblogs.com/hhelibeb/p/7376232.html
英文原文:Introduction to CDS Test Double Framework – How to write unit tests for ABAP CDS Entities?
挑战
因为CDS entity中的逻辑运行在下层的数据库中(独立于abap runtime),使用传统的ABAP依赖注入解决方案以实现测试成为了不可能的事情。entity的依赖组件需要在数据库中加上测试替身,并且我们必须确保CDS entity测试的时候数据库引擎调用/执行这些测试替身(double)。
为了可以在CDS entity under test (CUT)中可控地测试逻辑,我们需要通过测试替身注射测试专用数据。这意味着必须将测试数据插入到测试替身中,这样数据可以在CUT执行时被测试替身们返回。对于在ABAP CDS上下文中有着固有的只读属性的依赖组件(比如数据库视图和数据库函数),这是一项特别的挑战。
本文中重要的缩写:
CUT = CDS entity Under Test
DOC = Depended-On Component
CDS Test Double Framework
CDS Test Double Framework处理了以上的挑战,并且可以实现CDS entities测试的自动化:
- 在相同的Database Schema中为每个依赖组件创建临时的可更新测试替身:
- 复制依赖组件表,但不复制任何数据。不复制依赖数据库表的主键约束。这允许你轻松地插入测试数据,而不用担心数据的完整性。相似的,数据库索引也不会被复制。
- 为依赖数据库视图创建数据库表。这些表有着和依赖数据库视图相同的结构。
- 依赖数据库functions(由带有参数的依赖CDS视图和依赖表function产生)会被复制,并且function的测试替身实现会被修改为允许插入需要的测试数据。
- 在相同的Database Schema创建一个CDS entity under test(CUT)的临时副本。从各种意义上来看,这个副本是为CUT服务的。在原始的CDS entity中实现的逻辑在副本中同样存在,但是依赖组件被替换为了相应的测试替身。测试替身是由我们的CDS Test Double Framework所创建的。
测试什么?
单元测试应当专注于由一个给定视图实现的有价值的功能定义。不是所有的CDS视图都需要一个单元测试。在实现单元测试之前,建议辨别出entity中与测试有关的方面。
通常,需要为某些包含了代码下推的方法的entity进行单元测试。潜在的测试候选者包括:
Calculations and/or filters, conversions, conditional expressions 比如 CASE…THEN…ELSE or COALESCE, type changing CAST operations, cardinality changes or checks against NULL values, JOIN behavior, complex where conditions 等.
单元测试不应用于测试那些更适用于静态检查、集成测试等技术的CDS entities属性。如果不能从单元测试中获取任何价值的话,也不应进行它,比如对于那些简单的CDS投影视图。
怎样使用CDS Test Double Framework写单元测试?
在下一部分,我们会通过被广泛应用的ABAP Unit Test Framework为以下的CDS视图创建单元测试。
@AbapCatalog.sqlViewName: 'zSo_Items_By_1' @EndUserText.label: 'Aggregations/functions in SELECT list' @AbapCatalog.compiler.compareFilter: true
defineviewSalesorder_Items_By_TaxRateas select fromCdsFrwk_Sales_Order_Item
association[1] to snwd_so as _sales_order on so_guid =_sales_order.node_key
{
so_guid,coalesce ( _sales_order.so_id, '9999999999' ) asso_id,
currency_code,sum( gross_amount ) assum_gross_amount,
tax_rate,
_sales_order
}group byso_guid,
_sales_order.so_id,
currency_code,
tax_rate
SAP Gateway简介
SAP Gateway在S4/HANA时代的ABAP开发模型中有着重要的地位。SAP Gateway是什么?它对ABAP开发有怎样的影响?可以为我们提供哪些方便?这篇译文将浅要地讨论这些话题。
SAP NetWeaver Gateway是一项基于市场标准的技术,它提供了简单的方式以连接SAP软件与设备、环境和平台。这个框架允许实现创新的、以人为本的解决方案,为SAP的商务软件带来了新体验:比如社交与协作环境、手机和笔记本设备以及富internet应用。
简而言之,NetWeaver Gateway是一个ABAP组件集,它附加在你已有的SAP ERP系统上,并提供了简单的、以人为本的工具来访问你的业务信息,并且降低了消费数据所需要的知识门槛,使得使用者不需要了解SAP系统内部的工作机制。Gateway提供了易用的、定义良好的API,提供了入口以访问SAP系统中富有价值的业务数据和功能。
本文链接:http://www.cnblogs.com/hhelibeb/p/7600998.html
原文链接:A simple overview on SAP Netweaver Gateway
1.1 兼容性
- OPEN - 任何设备,任何体验,任何平台
- PEOPLE - 优化用户交互场景
- TIMELESS - 不分裂,任何SAP Business Suite版本
- DEVELOPERS - 简单的API,不需要SAP知识,任何工具(都可以)
- STANDARDS - 基于REST,ATOM/OData
SAP NetWeaver Gateway提供SAP应用与任何语言或模型的连接能力,借助REST services和OData/ATOM协议,实现这种连接不需要SAP方面的知识。
1.2 REST & OData
REST: 表现层状态转化(Representational State Transfer)是分布式系统的软件架构风格,例如万维网。凭借其更为简单的风格,REST已经逐渐代替了其它设计模型如SOAP。REST使用标准的GET, PUT, POST & DELETE方法和HTTP协议已有的特性。REST的主要目标包含组件交互的可测量性、接口的通用性、组件部署的独立性、中间组件减小延迟、增强安全性和封装遗留系统(legacy systems)等。
OData: 开放数据协议(Open Data Protocol)是一个用于查询和更新数据的开放的互联网协议。该协议允许消费者经由HTTP协议向数据源查询,并以Atom、JSON或者plain XML等格式返回数据,可以对数据编码、排序或者过滤。
1.3 关键优势
- REST允许你的系统由此降低消费数据的门槛,因为借助它,无需SAP系统的专业知识也能消费其中的业务数据和功能。
- 通过一个简单易用、非专有的接口,隐藏SAP系统背后的技术复杂性。
- 让你的SAP业务数据和功能可以从符合以下特性的任何设备访问:
- 通过HTTP(S)协议通信。
- 理解OData消息
- 提供服务生成工具(Service Provisioning tools),允许为已存在的ABAP功能快速生成REST实现。
- 为主流IDE提供插件,比如Eclipse,Visual Studio和Xcode.
2.0 使用开源工具访问SAP业务数据
通过SAP NetWeaver Gateway消费数据只需要用HTTP(S)请求即可。这不需要使用任何SAP先前的软件或协议。应用开发者通过SAP NetWeaver Gateway接口消费数据也不需要有ABAP编程经验,甚至完全不需要懂得SAP内部的工作原理。
使用通常的开发工具,比如微软的.NET和苹果的XCode,或者开源语言,比如Ruby和PHP,我们可以轻松地通过消费SAP服务器提供的OData消息为SAP业务数据和功能创建用户界面。为了让OData的消费处理变得更加简单,SAP发布了多个版本的Gateway Consumption Tool。这个工具现在可以在Visual Studio和Xcode中使用,它可以生成OData代理对象。另外,它也可以将已生成的代理对象包装并生成基本应用。
微软的OData协议基于Atom发布协议(Atom Publishing Protocol),相应地,该协议基于Atom 联合格式(Atom Syndication Format)。SAP利用了OData内建的标准扩展特性来提供自己的注解(Annotations)。OData数据格式和SAP注解的结合使得SAP业务信息同时实现了自描述和高可读性。这两个特性各自地降低了SAP业务信息和功能的获取门槛,使它们更易于为其它外部设备上的业务应用所利用。
3.0 聚焦SAP NetWeaver Gateway
SAP NetWeaver Gateway接口的焦点在于它的REST能力允许非SAP系统应用轻松地消费SAP的数据与功能。它们包括:
- 任何外部应用,比如微软Office应用可以通过.NET(甚至VBA)进行消费。
- 桌面机器可以通过由PHP、Java或Ruby等后台支持的Web应用进行消费。
- 移动端原生应用,比如iPad/iPhone或者安卓设备或者黑莓设备。
- 嵌入式设备,比如制造业机器人或者卫星导航系统中的路线规划软件。
- 任何你可以想到的可编程的、支持HTTP(S)协议的业务场景。
SAP NetWeaver Gateway接口可以用于任何支持HTTP(S)的可编程设备。为提供这一兼容性,它通过以下手段隐藏了系统内存在的复杂性:
协议适配:OData成为了向/从SAP系统供应/消费业务数据的唯一协议。
服务适配:不同类型和版本的SAP系统现在表现为单一的、集成的业务信息库。
4.0 开发过程
SAP NetWeaver Gateway软件由多种服务生成工具提供,它可以生成必要的源代码,以启动你的外部应用的开发。这些工具可以用于连接多种常用IDE,比如Eclipse,Visual Studio和Xcode。对这三个IDE,存在可用的扩展,所以开发者无需具备SAP知识。
SAP NetWeaver Gateway可以根据已有的BAPI、RFC和ABAP Dynpro屏幕创建新的Gateway对象。在生成Gateway对象时,生成工具使用起来和RFC生成器、BOR生成器和屏幕生成器一样。我们也可以通过Gateway附加组件来构建自定义Gateway对象,它会提供OData通道。这是一系列ABAP类和接口,可以用于在SAP系统中开发你自己的Gateway模型对象。需要在SAP NetWeaver Gateway中注册它们,这样就可以通过RESTful服务在外部访问。
可以通过以下图表轻松理解这些开发过程中的步骤:
5.0 总结
SAP NetWeaver Gateway不是用于由标准用户使用的事务型应用的通道,也不会替代现有的中间件如SAP NetWeaver PI。此外,SAP NetWeaver Gateway的目标也不是A2A或B2B场景。相反,SAP NetWeaver Gateway是一扇通往SAP业务数据和功能的门。它的目标受众是被称为临时平台用户(Occasional Platform Users ,OPU)的群体。这些人需要通过易于消费的方式实现特定的(ad hoc)SAP数据和功能访问。
abapGit简介与教程
你是ABAP开发者?你用abapGit吗?
看到这个问题,读者也许会想,什么是abapGit?就让我们从这个问题开始。简单地说,abapGit是一个以ABAP写成为ABAP服务的Git客户端。
有的读者可能依然感到困惑:什么是Git呢?这可能已经超出了本文的话题范围,请移步Google进行了解..
那么让我假设你在搜索之后已经返回了本文。Git是当代开发者的工具的基础部分,在我看来,在2017年的现在忽略它是不现实的。
本文链接:http://www.cnblogs.com/hhelibeb/p/7735421.html
原文标题:abapGit – so easy
回到主题,abapGit是一个开源项目,它由Lars Hvam发起,基于MIT许可证。
在本文撰写时,abapGit项目已经有30位贡献者,过去5个月中有超过500次commit,可见它是一个活跃而有生气的项目。也许看完本文后,你也会希望成为其中的一名贡献者,让项目变得更加壮大和优秀。
abapGit的设计目标之一是它应当“小型化”。这对很多人有着重要意义。其中之一即是,它会是迄今为止最易于安装的ABAP项目!没有传输,没有多个步骤,没有预安装,没有文件上传,没有补丁,不需要加载项。只要将代码复制粘贴到你的ABAP开发系统系统里,然后激活它。
就像这样(视频来自youtube,无法访问的话,请点击跳转到bilibili版):
安装完成后,你想做的第一件事大概就是连接GitHub,以保持你的abapGit代码是最新的。耶——这是个惊人的想法不是吗?我们可以在在自己喜欢的任何时间拉取abapGit项目的最近版本。Kapow! Take that CTS!(??) abapGit也有后台模式,所以你可以自动地完成更新任务。
你很可能希望为你的仓库使用Github。GitHub是当前最流行的Git托管平台,它免费,并且其中还包含某些极好的ABAP开源项目,比如abap2xlxs。
abapGit需要使用TLS与GitHub连接。这意味着我们必须在ABAP系统中通过事务STRUST安装某些些根证书。abapGit安装文档可以告诉你如何获取并安装这些证书。也有一个简单的测试程序帮助你确保连接Github成功。
如果你想要将abapGit连接到其它Git服务器,它们可能也会强制你使用TLS,因此你需要安装其它根证书,具体的根证书取决于他们的CA。
所以现在已经搞定了,让我们看看我们怎样连接到GitHub上面的abapGit仓库,以保持自己安装的abapGit是最新的。有一个向导可以帮助你。
当abapGit第一次运行的时候,它会给你一个abapGit教程页。你也可以通过菜单Help->Tutorial来找到它。点击“install abapGit repo"链接来启动连接过程。会出现提示,要求你确认安装到$ABAPGIT包中。abapGit连接Git仓库(repo)和ABAP包(package)。因此我们需要将abapGit本身存储在一个本地包中——在本例里面是$ABAPGIT。还会出现提示询问你是否要覆盖刚刚创建的ZABAPGIT程序,选择“OK"。激活所有abapGit组件,就可以完成了。视频(b站链接点我):
为完成这篇文章,让我举个能让你理解abapGit是如何改变ABAP开发者的工作的例子,带你经过一个简单的场景。我们需要以clone一个到ABAP包里作为开始。我会使用到我最近的一段有关构建Gateway Service的示例代码,代码在这里:https://github.com/grahamrobbo/teched16_example.
视频如下(b站链接点我):
看看它有多简单,几个点击就可以从GitHub拉取所有的ABAP代码到一个我在abapGit界面中创建的包里,并且激活了所有的的东西。Kapow!
现在注意,我想我的代码需要点重构了,我决定删掉接口ZIF_GW_METHODS,因为我忘记这个东西在哪里能用到。我因此丢掉了重要的代码,程序遭到了破坏,而我无法激活任何东西。Arrrggghhhh...我想我只能登陆生产系统,复制粘贴旧版的代码,然后从头开始——假设我还能记住自己做过的修改的话。
或者——我可以只是刷新我的包为上次commit到GitHub repo的状态。并且因为我“commit early and commit often”,我并没有因此丢掉我的工作进展。视频(b站链接点我):
Kapow!
这只是将Git引入到ABAP开发者工具中的好处之一。
abapGit官方文档:abapGitdocumentation