自制流水码获取-优化

文章讲述了在IT系统中,为解决数据锁定问题和提高流水码获取效率,引入了批次概念,并详细描述了ZFMBC_TEST_GET_NUMBER和ZFMBC_TEST_GET_NUMBER_BATCH这两个函数的工作原理,包括数据锁定处理、批次划分以及错误处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最开始获取流水码时,只有log_key 和idx两个字段,在实际使用中,经常遇到数据被锁定,导致获取流水码失败,因此引入批次的概念。

表设计:

函数信息:

FUNCTION zfmbc_test_get_number.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(I_LOG_KEY) TYPE  ZTEST_04-LOG_KEY
*"     REFERENCE(I_ERDAT) TYPE  SY-DATUM DEFAULT SY-DATUM
*"     REFERENCE(I_COUNT) TYPE  INT4 DEFAULT 1
*"     REFERENCE(I_FILL_CNT) TYPE  INT4 DEFAULT 6
*"     REFERENCE(I_GROUP) TYPE  INT4 DEFAULT 3
*"  EXPORTING
*"     VALUE(E_SERIALSTR) TYPE  CLIKE
*"     VALUE(ET_SERIALSTR) TYPE  ZTBC_SERIALSTR
*"  EXCEPTIONS
*"      ERROR
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& DEVELOPER            < 开  发>: 
*& CREATE ON            <创建日期>:  2024-04-10
*& FS NUMBER            <FS 编号>:
*& FUNCTIONAL CONSULTANT<功能顾问>:
*& DESCRIPTION          <FS 中业务需求概述>:
*&
*&---------------------------------------------------------------------*
*              MODIFICATION LOG<程序修改日志,创建时不要填写>
*<版本>       <日期>        <开发者>     <功能顾问>   任务编号    <请求号>
*VERSION      DATE        PROGRAMMER   CORR. #       IL#        TRANSPORT
*   1         YYYY/MM/DD
*DESCRIPTION<程序逻辑修改 版本1> :
*
*DESCRIPTION<程序逻辑修改 版本2> :
*
*&---------------------------------------------------------------------*

  "注意:LOG_KEY 只有一个I_GROUP,否则数据异常


  DATA:
    lv_count     TYPE i, "剩余条数
    lv_batch     TYPE ztest_04-batch, "批次
    lv_group     TYPE i, "分组处理
    lt_serialstr TYPE ztbc_serialstr.

  lv_group = i_group.

  DO lv_group TIMES.

    "批次
    lv_batch = sy-index.
    "剩余编码条数
    lv_count = i_count - lines( et_serialstr ).
    "判断是否获取足够条码
    IF lv_count < 1.
      EXIT.
    ENDIF.

    CALL FUNCTION 'ZFMBC_TEST_GET_NUMBER_BATCH'
      EXPORTING
        i_log_key    = i_log_key
        i_erdat      = i_erdat
        i_count      = lv_count
        i_fill_cnt   = i_fill_cnt
        i_batch      = lv_batch
        i_group      = i_group
      IMPORTING
        et_serialstr = lt_serialstr
      EXCEPTIONS
        error        = 1
        OTHERS       = 2.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.

    "汇总条码
    IF lt_serialstr[] IS NOT INITIAL.
      APPEND LINES OF lt_serialstr TO et_serialstr.
      CLEAR lt_serialstr.
    ENDIF.

  ENDDO.

  READ TABLE et_serialstr INTO e_serialstr INDEX 1.
  IF i_count NE lines( et_serialstr ).
    MESSAGE '编码获取失败' TYPE 'E' RAISING error.
  ENDIF.
ENDFUNCTION.

FUNCTION zfmbc_test_get_number_batch .
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(I_LOG_KEY) TYPE  ZTEST_04-LOG_KEY
*"     REFERENCE(I_ERDAT) TYPE  SY-DATUM
*"     REFERENCE(I_COUNT) TYPE  INT4
*"     REFERENCE(I_FILL_CNT) TYPE  INT4
*"     REFERENCE(I_BATCH) TYPE  ZTEST_04-BATCH
*"     REFERENCE(I_GROUP) TYPE  INT4
*"  EXPORTING
*"     REFERENCE(ET_SERIALSTR) TYPE  ZTBC_SERIALSTR
*"  EXCEPTIONS
*"      ERROR
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& DEVELOPER            < 开  发>: 
*& CREATE ON            <创建日期>:  2024-04-10
*& FS NUMBER            <FS 编号>:
*& FUNCTIONAL CONSULTANT<功能顾问>:
*& DESCRIPTION          <FS 中业务需求概述>:
*&
*&---------------------------------------------------------------------*
*              MODIFICATION LOG<程序修改日志,创建时不要填写>
*<版本>       <日期>        <开发者>     <功能顾问>   任务编号    <请求号>
*VERSION      DATE        PROGRAMMER   CORR. #       IL#        TRANSPORT
*   1         YYYY/MM/DD
*DESCRIPTION<程序逻辑修改 版本1> :
*
*DESCRIPTION<程序逻辑修改 版本2> :
*
*&---------------------------------------------------------------------*


  DATA:
    lv_group     TYPE i,
    lv_seq_numc  TYPE n LENGTH 20    , " 流水号补位
    lv_serialstr TYPE string,
    lv_begindex  TYPE i,
    lv_endindex  TYPE i,
    ls_ztest_04  TYPE ztest_04.

  CONSTANTS lc_connection TYPE char50 VALUE 'R/3*ZTEST_04'.


  "分组初始值
  lv_group    = i_group.
  IF lv_group IS INITIAL.
    lv_group = 1.
  ENDIF.

  "起始编码
  lv_begindex = 1000000 DIV lv_group * ( i_batch - 1 ).
  lv_endindex = 1000000 DIV lv_group * i_batch.
  IF lv_endindex = 1000000.
    lv_endindex = 999999.
  ENDIF.

  "KEY
  ls_ztest_04-log_key = i_log_key && i_erdat+2(6).
  "批次
  ls_ztest_04-batch   = i_batch.

  "锁定数据
  CALL FUNCTION 'ENQUEUE_EZ_ZTEST_04'
    EXPORTING
      mode_ztest_04  = 'E'
      mandt          = sy-mandt
      log_key        = ls_ztest_04-log_key
      batch          = ls_ztest_04-batch
      x_log_key      = ' '
      x_batch        = ' '
      _scope         = '3'
      _wait          = ' '
      _collect       = ' '
    EXCEPTIONS
      foreign_lock   = 1
      system_failure = 2
      OTHERS         = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
    RAISING error.
  ENDIF.

  "获取数据库条码
  SELECT SINGLE idx
    FROM ztest_04
    WHERE log_key = @ls_ztest_04-log_key
      AND batch   = @ls_ztest_04-batch
    INTO @ls_ztest_04-idx.

  IF ls_ztest_04-idx < lv_endindex.

    "防止跨批次执行
    IF ls_ztest_04-idx < lv_begindex.
      ls_ztest_04-idx = lv_begindex.
    ENDIF.

    "循环取号
    DO i_count TIMES.
      "序号赋值
      lv_serialstr = lv_seq_numc  = ls_ztest_04-idx = ls_ztest_04-idx + 1.
      "填充0
      SHIFT lv_serialstr LEFT BY ( 20 - i_fill_cnt ) PLACES.
      "汇总
      lv_serialstr = |{ ls_ztest_04-log_key }{ lv_serialstr }|.
      APPEND lv_serialstr TO et_serialstr[].

      IF ls_ztest_04-idx >= lv_endindex.
        EXIT.
      ENDIF.
    ENDDO.

    "更新数据库
    MODIFY ztest_04 CONNECTION (lc_connection) FROM ls_ztest_04 .
    IF sy-subrc EQ 0.
      COMMIT CONNECTION (lc_connection).
    ELSE.
      ROLLBACK CONNECTION (lc_connection).
      CLEAR et_serialstr[].
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      RAISING error.
    ENDIF.

  ENDIF.

  "解锁
  CALL FUNCTION 'DEQUEUE_EZ_ZTEST_04'
    EXPORTING
      mode_ztest_04 = 'E'
      mandt         = sy-mandt
      log_key       = ls_ztest_04-log_key
      batch         = ls_ztest_04-batch
      x_log_key     = ' '
      x_batch       = ' '
      _scope        = '3'
      _synchron     = ' '
      _collect      = ' '.

ENDFUNCTION.

测试:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值