CURRENT_IDENTITY_VALUE不一致

2020-09-23 20:07发布

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

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


似乎 CURRENT_IDENTITY_VALUE()函数在您的会话中至少有两个带有标识列的表时,HANA中的内容可能会混乱。 只需尝试以下示例代码:

创建列表test1(id整数,不为null,默认情况下作为标识生成主键,x整数);
 创建列表test2(id整数,不为null,默认情况下作为标识生成的主键,x整数);

 创建过程temp_identity_p为
   我整数;
   j整数;
 开始
   对于我1..500
     插入test1(x)值(:i);
     从哑元中选择current_identity_value()到j中;
     如果我> 100,那么
       插入test2(x)值(:j);
     万一;
   结束于
 结束;

 调用temp_identity_p;

 从test1中选择*,其中id <> x;
 从test2选择*,其中id <> x-100按ID排序; 

执行过程后,test1表看起来像预期的那样。 值从1到500," id"和" x"列中的值相同。

但是在test2中,x应该来自test1.id(有点类似于它的链接),延迟为100。所以您期望:

1,101

2,102

3、103等

但并非每条记录都是如此。

4,3

5,4

记录如下。 看起来CURRENT_IDENTITY_VALUE()有时是从test2的最后一个插入而不是test1获得其值的。 但是,很明显,在插入test1之后立即执行CURRENT_IDENTITY_VALUE()。

这非常危险,因为它可能会使您的代码中的外键弄乱。

您知道该问题的任何解决方案吗?

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

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


似乎 CURRENT_IDENTITY_VALUE()函数在您的会话中至少有两个带有标识列的表时,HANA中的内容可能会混乱。 只需尝试以下示例代码:

创建列表test1(id整数,不为null,默认情况下作为标识生成主键,x整数);
 创建列表test2(id整数,不为null,默认情况下作为标识生成的主键,x整数);

 创建过程temp_identity_p为
   我整数;
   j整数;
 开始
   对于我1..500
     插入test1(x)值(:i);
     从哑元中选择current_identity_value()到j中;
     如果我> 100,那么
       插入test2(x)值(:j);
     万一;
   结束于
 结束;

 调用temp_identity_p;

 从test1中选择*,其中id <> x;
 从test2选择*,其中id <> x-100按ID排序; 

执行过程后,test1表看起来像预期的那样。 值从1到500," id"和" x"列中的值相同。

但是在test2中,x应该来自test1.id(有点类似于它的链接),延迟为100。所以您期望:

1,101

2,102

3、103等

但并非每条记录都是如此。

4,3

5,4

记录如下。 看起来CURRENT_IDENTITY_VALUE()有时是从test2的最后一个插入而不是test1获得其值的。 但是,很明显,在插入test1之后立即执行CURRENT_IDENTITY_VALUE()。

这非常危险,因为它可能会使您的代码中的外键弄乱。

您知道该问题的任何解决方案吗?

付费偷看设置
发送
7条回答
wang628962
1楼-- · 2020-09-23 20:48

虽然这可能无济于事,但是您可以通过创建特定序列(sq_mysequence)并从表中删除身份密钥并自己进行管理,并在执行插入操作时(或在将插入操作插入test1之前,将其调用为sq_mysequence.nextvalue。 将其放在变量中,然后将其重新用于test2中的所有后续插入)。

大道至简
2楼-- · 2020-09-23 20:51

感谢您的回答和您的时间!

我们的修订版本是112.03,但奇怪的是,现在一切对我也很好。

这很尴尬,但我无法重现。 自从我的帖子以来,没有任何版本更改。 也许此行为是由某些设置或巧合引起的,此后已更改。 但是我确定我花了很多时间,这给我们带来了很多麻烦。 我真的不明白...

宇峰
3楼-- · 2020-09-23 20:42

您的数据库的修订版是什么? 在122.05上执行此操作,将在test2选择查询中返回结果。 手动查看所有结果,对我来说似乎很好。

大简至美
4楼-- · 2020-09-23 20:46

谢谢!

顺序是一种方法,而不是自动生成的标识和current_identity_value。

我认为,由于线程问题,在任何情况下使用current_identity_value都毫无意义。

Cikesha
5楼-- · 2020-09-23 20:29

For(1..500)可能并行执行。 current_identity_value可能不会从该线程返回最后插入的值,而是任何线程。 在您的情况下,开始并插入i = 100的foreach的执行,然后在i = 1并插入的地方处理另一个线程。 然后代码切换回选择current_ident_value并得到1?

与其使用current_identity_value而不是正确的值,因为它会混合从任何表创建的标识以及线程和会话,而是主动获取要使用的序列,然后将其推送到子表。 您最终将获得更少的问题。 这是草稿,但我不确定会不会编译

在mssql上,您可以通过使用输出close来修复此问题,以返回该特定插入的插入主键,但是就插入文档而言,似乎在hana上是不可能的。

创建列表test1(id整数不为null主键,x整数);
 创建列表test2(id整数不为null主键,x整数);
 创建序列sq_test1;
 创建序列sq_test2;

 创建过程temp_identity_p为
   我整数;  sq_i整数;
   j整数;
 开始
   对于我1..500
     将selelct sq_test1.nextval从虚拟对象转换为sq_i;
     插入test1(id,x)值(:sq_i,:i);
    
     如果我> 100,那么
       插入test2(id,x)值(sq_test2.nextval,:sq_i);
     万一;
   结束于
 结束;


 
哎,真难
6楼-- · 2020-09-23 20:54

糟糕,我又做了一次。 :)

在我上次使用的同一SQL控制台窗口中。 但是上次它拒绝混淆结果,现在又做了。

一周热门 更多>