云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

消息队列_阿里云vpn网关_免费申请

小七 141 0

这是一个穷人在SQL中读取DF34\ U原始数据类型的实现。

简介

为了在本机HANA中为SAP的ACM模块构建BI报告,我们遇到了许多使用以DF34\ U原始格式存储的十进制128位浮点数的表。由于这是本机ABAP类型,因此无法在SQL中直接读取。我们已经在HANA中构建了很多计算视图和报告,所以我们必须有一种方法从这些字段中获取值。与SAP支持部门的讨论并没有带来解决方案,物联网大会,因此我开始寻找一种替代的原生SQL方法。

我们已经使用这种方法一段时间了,所以我认为分享我们的想法很好。

二进制结构

当我开始时,我天真地试着看看DF34èRAW是否有与之相同的内部工作原理https://en.wikipedia.org/wiki/Decimal128\浮点\格式。

虽然结构看起来很相似,但表现却不尽相同。下面是我对用例格式的理解。不要指望这是完整的或100%正确。

这里:

s表示符号位cccc是10位declet,只能作为最大值为999的整数读取。(对于负号位,值是反计数的。所以999-值)标志十二月价值1000000000000010001101100083111111001119990000000000099901111100111000mmmm包含最高有效位和指数值。这个组合的部分可以以与declets类似的方式读取为整数。在组合部分中,大数据精准,我们可以查看第一个数字以找到最有效的数字。(对于负号位,它是9-值)对于指数,我们忽略第一个数字并减去6176(因为128位浮点数支持±000000000000000000000000000x10^-6176到±999999999999999999999999999999999999×10^6111的范围)。对于负号位,数据分析法,指数有点不同。标志结合int值指数材料安全数据表价值10111101 10111111016176505510111101 110000001161771111010111101 1100001111617832三300

挑战

要在SQL中实现这一点,我们有两个挑战:

挑战1可以通过使用BITAND函数屏蔽位字段,通过BINTOHEX将二进制值转换为十六进制VARCHAR,然后使用子字符串选择范围来克服。因为我们使用十六进制值,所以每次选择4位的倍数。我们所能做的就是为每个declet选择12位而不是10位,所以我们的一些范围是2位未对齐的。这意味着我们需要对一些值进行位移(或者简单地除以4)。

挑战2变得更难了,因为我们现在有十六进制字符串而不是二进制值。不存在此的本机函数。博客帖子https://archive.sap.com/discussions/thread/3652555试图通过使用while循环的标量UDF函数来解决这个问题。虽然它可以工作,但性能尤其是中间内存分配非常糟糕。因此,我选择了数据库擅长的东西:查找表。就我们的目的而言,我们只有1000个不同的值。在我们的查找表中,我们还可以处理位移位的问题。

实现

最初我想要一些模块化和可重用的东西,所以我构建了几个标量UDF函数,可以为任何包含DF34\ U原始值的列调用。然而,这对性能来说是相当糟糕的。每个UDF为它处理的每个行项目分配了数Mb的内存。对于一些大型数据集,我注意到在执行期间分配和释放了数TB的内存。使用查找表和简单的左连接重写逻辑使事情变得更简单,并确保性能不会太差。缺点是需要为每个表和每个源字段实现它。

最后,我的逻辑是将DF34\u原始字段拆分为14个单独的字段,然后对查找值执行13个联接,物联网公司排名,最后以字符串格式将其合并到一起,可以传递给to\u DECIMAL函数,喜欢使用十进制(1.231e2)。

不要用难以格式化的代码把这篇文章弄得乱七八糟,整个例子可以在:https://github.com/maxnuf/df34\u原始\u对流。

我仍然希望有一天HANA中的本机转换功能可以使用。同时,我也希望这个实现能帮助其他需要用SQL读取DF34èu原始值的人。

我知道这个实现并不完美,淘客api,所以欢迎提出改进的想法和建议。