存储过程,其中输入和输出是整数列表

2020-09-17 06:34发布

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

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


我有一种情况,我想创建一个存储过程,该过程将整数ID的列表作为输入。 该过程需要用每个ID更新两个表,如果其中一个更新失败,则该ID的更新应完全失败。 我希望能够返回该过程完成后失败的所有ID的列表。 我知道我可以在过程中进行事务处理以确保全部成功或全部失败,但是我不确定是否可以将列表传递给过程。 我在网上四处张望,但没有发现任何帮助

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

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


我有一种情况,我想创建一个存储过程,该过程将整数ID的列表作为输入。 该过程需要用每个ID更新两个表,如果其中一个更新失败,则该ID的更新应完全失败。 我希望能够返回该过程完成后失败的所有ID的列表。 我知道我可以在过程中进行事务处理以确保全部成功或全部失败,但是我不确定是否可以将列表传递给过程。 我在网上四处张望,但没有发现任何帮助

付费偷看设置
发送
2条回答
灬番茄
1楼 · 2020-09-17 06:57.采纳回答

史蒂夫嗨,

感谢您在此处发布此信息,以便其他人可以贡献并使用此问题。

根据您的描述,您有几个要求:

  • 过程中记录ID的过程列表
  • 保留未处理的ID列表
  • 在过程调用上保持事务一致性

一种解决方法如下:

从m_database中选择current_timestamp,*;
/*
 CURRENT_TIMESTAMP SYSTEM_ID DATABASE_NAME主机START_TIME版本的使用情况
 2018年6月21日12:18:19.605 S12 S12头骨盒2018年6月20日10:04:22.642 PM 1.00.122.16.1520578817自定义
 */
 创建列表a(id int,名称nvarchar(20));
 创建列表b(id int,名称nvarchar(20));


 插入值(1,NULL);  -在两个表中都存在
 插入b值(1,NULL);
 插入值(2,NULL);  -仅存在于A中
 插入b值(3,NULL);  -仅存在于B中
 插入值(5,NULL);  -ID 4根本不存在
 插入b值(5,NULL);  -两个表中都存在ID 5

 选择a.id作为A_ID,选择a.name作为A_NAME
      ,b.id为B_ID,b.name为B_NAME
 来自完整的外部连接b
 在a.id = b.id上
 通过结点排序(a.id,b.id);

/*
 A_ID A_NAME B_ID B_NAME
 1个 1个
 2?  ?  ?
 ?  ?  3个?
 5?  5?
 */
 创建全局临时表GT_FAILED_IDS(id int,failed_update nvarchar(10));

 删除过程upd_data;
 创建过程UPD_DATA(在upd_ids TABLE(id int)中,
                                       out failed_ids TABLE(id int
                                                           ,failed_update nvarchar(10))
                                                      )
 如
 开始
 从:upd_ids声明选择ID的游标批处理列表;
    对于cur_row作为批处理列表
         更新集合名称='PROCESSED_A',其中id = cur_row.id;
         如果:: ROWCOUNT = 0,则
             插入GT_FAILED_IDS
                 值(cur_row.id,'A');
         万一;
         更新b集名称='PROCESSED_B'其中id = cur_row.id;
         如果:: ROWCOUNT = 0,则
             插入GT_FAILED_IDS
                 值(cur_row.id,'B');
         万一;
    结束于
    failed_ids =选择ID
                      ,string_agg(failed_update,',')为failed_update
                 来自GT_FAILED_IDS
                 按ID分组;
    承诺;
 结束;

 -测试程序
 开始
     -选择ID 1,2,3,4,5
     in_ids =从哑元中选择1作为ID
              全部合并
              从虚拟中选择2作为ID
              全部合并
              从虚拟中选择3作为ID
              全部合并
              从假人中选择4作为ID
              全部合并
              从虚拟中选择5作为ID;
     调用upd_data(:in_ids,:out_ids);
     选择'OUT:',* from:out_ids;
 结束;
/*
 'OUT:'ID FAILED_UPDATE
 输出:2 B
 输出:3 A
 出:4 A,B
 */

 选择a.id作为A_ID,选择a.name作为A_NAME
      ,b.id为B_ID,b.name为B_NAME
 来自完整的外部连接b
 在a.id = b.id上
 通过结点排序(a.id,b.id);

/*
 A_ID A_NAME B_ID B_NAME
 1个PROCESSED_A 1个PROCESSED_B
 2个PROCESSED_A吗?  ?
 ?  ?  3个PROCESSED_B
 5 PROCESSED_A 5 PROCESSED_B
 */

在这里,使用全局临时表来跟踪失败的ID并不是硬性要求。 另外,我仅关注未找到要更新的记录的情况。 您可能需要检查更多/不同的故障情况。

这种方法的主要部分当然是:使用表类型的参数来处理列表和:: ROWCOUNT会话变量。

希望可以为您指明正确的方向。

干杯

Lars

nice_wp
2楼-- · 2020-09-17 07:12

是的,正确。 如果要确保已执行所有更新或不执行与一个ID相关的更新,则可以,您可以在过程中使用事务。

这没问题,您可以在过程中简单地发出COMMIT或ROLLBACK。 请注意,这不是子交易。 因此,您将需要确保在调用该过程之前,未在会话中提交其他更改。

一周热门 更多>