SAP Hana JSON_TABLE和主键表列

2020-08-14 11:44发布

点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)我很惊讶,因为我似乎无法解决一个...

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

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


我很惊讶,因为我似乎无法解决一个简单的问题:如何显示表格的其他列?

我正在读取包含Json数据的文本列,并使用JSON_TABLE函数将内容分开。 让我们使用 help.sap.com 。 该表T1具有用作主键的列A和具有Json有效负载的列B。

示例中的select语句为:

选择*
 从JSON_TABLE(T1.B,'$ .LineItems [*]'
 列
     (
         ITEM_NUMBER INT PATH'$ .ItemNumber',
         UPC_CODE BIGINT PATH'$ .Part.UPCCode'
     )
 ); 

但是如何将T1.A列添加到结果集中? 当读取具有多个条目的表时,将需要主键!

有人指针吗?

5条回答
Bunny_CDM
2020-08-14 12:26 .采纳回答

非常感谢我,麦克·艾普比 WernerDähn

事实证明,这很……嗯,"有趣" ...

让我们先退后一步, 看看我们要在这里做什么。

有一个表T1,T1中的每个条目都附加了一个完整的JSON文档,整齐地存储在" JSON"列B中。 现在,JSON_TABLE()表函数将另一列作为输入并返回一个表。

此返回表的结构和内容取决于JSON_TABLE()参数和数据中定义的内容。 让我们暂时搁置这一点。

鉴于此,我们可以说:" 太好了,那么我们只需将T1中每一行的B值馈入此表函数,我们就很好了"。

眼神敏锐的SQL开发人员现在看到:这是LATERAL"联接"的"每行"操作。 而且,实际上,查看有关该函数应如何工作的描述,这就是JSON_TABLE()的作用。 (请参阅P.S.)

听起来不错,让我们尝试一下!
(注意:我在测试表T1中创建了第二个条目,以便我们实际上可以看到"每行"操作)。

选择
     x.A,JT。*
 从
     T1 x
     ,JSON_TABLE(x.B,'$。LineItems [*]'
                 列
                     (
                         ITEM_NUMBER INT PATH'$ .ItemNumber',
                         UPC_CODE BIGINT PATH'$ .Part.UPCCode'
                     )
                 )JT;
 

但是HANA说:否!

无法执行'SELECT xA,JT。* FROM T1 x,JSON_TABLE(xB,'$ .LineItems [*]'COLUMNS(ITEM_NUMBER INT 路径...'
 SAP DBTech JDBC:[259]:无效的表名:表不存在> X:第5行第19列(在pos 44处)

在我看来,这看起来像是HANA中的错误。

它应该接受列引用,并在此处执行JSON_TABLE()函数的"横向"应用程序。

那么,如何解决此问题而不必等待新的HANA补丁?
也许我们可以通过使用HANA 2 SPS 04引入到HANA的LATERAL JOIN功能(这是我使用的版本2.00.045 HANA Express Edition)来做自己的"横向"应用程序 )。

选择
     T1.A,JT。*
 从
     T1
     ,LATERAL(SELECT * FROM JSON_TABLE(T1.B,'$ .LineItems [*]'
                         列
                             (
                                 ITEM_NUMBER INT PATH'$ .ItemNumber',
                                 UPC_CODE BIGINT PATH'$ .Part.UPCCode'
                             )
                         )
              JT;
 

此方法不会产生错误,但也不会执行我们想要的操作:

 ITEM_NUMBER UPC_CODE
 1 1 73,649,587,162
 1 2 83,600,229,374
 1 3 33,298,003,521
 1 4 91,827,739,856
 1 5 22,983,303,876
 1 1 200,007,162
 1 2 200,009,374
 1 3 200,003,521
 1 4 200,009,856
 1 5 200,001,876
 2 1 73,649,587,162 <-T1中的第二条记录从此处开始
 2 2 83,600,229,374
 2 3 33,298,003,521
 2 4 91,827,739,856
 2 5 22,983,303,876
 2 1 200,007,162
 2 2 200,009,374
 2 3 200,003,521
 2 4 200,009,856
 2 5 200,001,876
 

因此,HANA在这里决定不有效执行交叉联接,而这并不是我们所要求的。

下一个想法:
真的,实际上只是给它提供了标量值,并使用LATERAL联接中的结果。

为此,我们需要一个自定义表函数,如下所示:

创建或替换函数tbl_ItemNoCode
                            (B_JSON NVARCHAR(5000))
 返回表(ITEM_NUMBER INT,
                 UPC_CODE BIGINT)
 如
 开始
     返回SELECT ITEM_NUMBER,UPC_CODE
             从JSON_TABLE(:B_JSON,'$ .LineItems [*]'
             列
                 (
                     ITEM_NUMBER INT PATH'$ .ItemNumber',
                     UPC_CODE BIGINT PATH'$ .Part.UPCCode'
                 )
             );
 结束;
 

我们需要像这样在LATERAL联接中使用此表函数:

 SELECT
     x.A,JT。*
 从
     T1 x
     ,LATERAL(tbl_ItemNoCode(x.B))JT;  

最后,我们得到了一直在寻找的东西:

一个ITEM_NUMBER UPC_CODE
 1 1 73,649,587,162
 1 2 83,600,229,374
 1 3 33,298,003,521
 1 4 91,827,739,856
 1 5 22,983,303,876
 2 1 200,007,162 <-这是第二条记录的数据
 2 2 200,009,374
 2 3 200,003,521
 2 4 200,009,856
 2 5 200,001,876
 

简而言之:使用自定义表功能解决(很可能)HANA错误。

干杯, 拉尔斯

P.S。

我似乎怎么知道这个新功能应该做什么? 因为疯狂的Google-skillz ;-):

*这个用于MariaDB的JIRA项目很好地涵盖了该主题( https://jira.mariadb.org/browse/MDEV-17399 ),并具有指向其他资源的链接(如下)

* Modern-SQL概述了新功能 SQL:2016( https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016 ),其中包含指向JSON_TABLE

* SQL-Standard文档(部分 6:SQL对JavaScript对象表示法(JSON)的支持)( https://standards。 iso.org/ittf/PubliclyAvailableStandards/c067367_ISO_IEC_TR_19075-6_2017.zip

一周热门 更多>