表池 DBIF_RSQL_SQL_ERROR 错误解决

问题描述

在 VK 中,当在业务系统中更改了某个 key 值的长度,得到了更新中断,dump 类型是 DBIF_RSQL_SQL_ERROR,同样的症状也可能出现在:

  • 在事务 VK11/ME11 等中获取短转储,出现错误 DBIF_RSQL_INVALID_RSQL
  • 事务 SM21 显示表 KAPOL 的转换错误
  • 如果通过 SE12 检查表 KAPOL,则报告数据对象不一致

由于这种不一致,对这些池中的逻辑表的访问可能会触发不同的运行时:

  • 运行时错误 DBIF_RSQL_INVALID_RSQL
  • 运行时错误 DBIF_RSQL_INTERNAL_ERROR
  • 客户端副本的逻辑池表仍然可以被识别为有错误并相应地在日志中列出:DDIC 错误(参见 SE14

在多个表池中,运行时对象中 VARDATA 字段的长度与数据库中字段的长度不一致。通过选择 "SE11 -> (显示表)-> 实用程序 -> 数据库对象 -> 检查 "启动 ABAP 字典中的一致性检查,显示受影响表池的字段 VARDATA 存在不一致。以下表池可能受到影响:

  • ATAB
  • DVPOOLTEXT
  • GLSP
  • GLTP
  • KAPOL

在我的系统中,会发现表池 DVPOOLTEXTVARDATA 的字段长度为 16384,如下图:

可以看到,数据库对象的 VARDATA 字段长度为 16384 ,而运行时对象的 VARDATA 字段长度为 8192。所以问题是字典和运行时对象的字段 VARDATA 的长度是数据库对象的两倍。由于数据库对象和运行时对象不一致,出现 dump DBIF_RSQL_SQL_ERROR 。同样的问题也可能发生在其他表池上,例如 ATABKAPOLGSLPGLSPGLTP 等。

原因

程序 UMG_POOL_TABLE 在 Unicode 转换或在 UNICODE 上重新安装期间执行。该程序决定在 Unicode 转换期间必须转换的所有表池的 VARDATA 字段是否必须扩展,并将新计算的长度写入表池的 DDIC 源和运行时对象。程序 RADPOCNV 或自 SAPKB70011 起,功能模块 DD_POOL_CNV 用于此目的。

如果在 Unicode 转换后程序 UMG_POOL_TABLE 现在被执行多次(例如手动),则 ABAP 字典和运行时对象中的长度会被拉长数倍,并且表池的运行时对象与相应的运行时对象之间指定的不一致。数据库中的表发生。每次执行程序 UMG_POOL_TABLE 时,日志都会将数据写入名为 TPOCNV* 的数据库。要检查日志,您可以使用报表 RADPROTA 显示它们。

解决方案

官方的解决方法是使用报表 RATPONTC 将字典和运行时对象的字段 VARDATA 的长度重置为与数据库对象的长度相同。如果你的 SAP 不存在这段程序,可以参考如下代码将它们复制到本地磁盘并按照 SAP Note 13719 实施。

ABAP 复制代码
*&---------------------------------------------------------------------*
*& Report  RATPONTC
*&
*&---------------------------------------------------------------------*
*& Sets VARDATA length
*&
*&---------------------------------------------------------------------*
report  ratpontc.

include radbtmac.
include radbtoum.
include radbtlom.

data: prid like syst-tabix,
      rc like syst-subrc.

*-Define-Selection-screen----------------------------------------------*
* Begin: Define parameter-screen
  selection-screen begin of block env with frame title text-003.
*   Begin: Choose Objects to move
    selection-screen begin of block obj with frame title text-004.
      parameters: sqltab like dd06l-sqltab obligatory,
                  length type dd16s-intlen obligatory.
      parameters uc as checkbox.
      parameters settmst as checkbox default 'X'.
    selection-screen end of block obj.
*   End: Choose Objects to move
*   Begin: Define log-parameters
    selection-screen begin of block log with frame title text-003.
      parameters: logname(30) default 'SETPOLN&DATE&&TIME&',
                  file     radiobutton group lgwr,
                  database radiobutton group lgwr,
                  log_show as checkbox default 'X'.
    selection-screen end of block log.
*   End: Define log-parameters
  selection-screen end of block env.
* End: Define parameter-screen

*-Main-program---------------------------------------------------------*
  start-of-selection.

* Open log
  perform log_handle using 'X' file database logname prid rc.

* Handle object
  level_add> prid.
  perform object_handle using sqltab length uc settmst rc prid.
  level_sub> prid.

* Close log
  perform log_handle using ' ' file database logname prid rc.
  if log_show = 'X'.
*   Show log
    display> prid 1.
  endif.


*&---------------------------------------------------------------------*
*&      Form  OBJECT_HANDLE
*&---------------------------------------------------------------------*
*       Handles tablepool
*----------------------------------------------------------------------*
*      -->sqltab: Object to handle
*      -->length: length of VARDATA field
*      -->uc    : 'X': unicode-length, ' ': non-unicode-length
*      -->settmst: 'X': set timestamp and uuid
*      <--rc   : Total returncode for all objects
*----------------------------------------------------------------------*
form object_handle using sqltab type dd06l-sqltab
                         length type dd16s-intlen
                         uc settmst
                         rc like syst-subrc
                         prid like syst-tabix.

data: dd06v_wa type dd06v,
      dd06v_wa_a type dd06v,
      dd16v_wa like dd16v,
      dd16v_tab like dd16v occurs 0 with header line,
      dd16v_tab_a like dd16v occurs 0 with header line,
      got_state type dcsqltget.
data: messtext(80).
data: tabtname type dd09l-tabname,
      tabt_got_state type ddrefstruc-state.
data: dd02v_wa type dd02v,
      dd03p_tab like dd03p occurs 0 with header line,
      dd03p_wa  like dd03p,
      dd08v_tab like dd08v occurs 0 with header line,
      dd09l_wa like dd09l,
      x030l_wa like x030l,
      x030l_wa_old like x030l,
      x031l_tab like x031l occurs 0 with header line,
      uuid type sysuuid-x,
      timestamp_new(14).
data: ntab_rc like syst-subrc.
data  tabname like x030l-tabname.
data unicodelg like x030l-unicodelg.

  call 'CUR_LCL' id 'UC_LN' field unicodelg.
  if unicodelg <> '02'.
    messtext = text-011.
    replace '&' in messtext with sqltab.
    str> prid messtext.
    exit.
  endif.

  messtext = text-010.
  replace '&' in messtext with sqltab.
  str> prid messtext.

* Initialize returncode
  rc = 0.

* Read tablepool
  call function 'DD_SQLT_GET'
    exporting
*     GET_STATE            = 'M'
*     LANGU                = SY-LANGU
      name                 = sqltab
*     PRID                 = 0
*     WITHTEXT             = ' '
*     TRACELEVEL           = 0
    importing
      dd06v_wa_n           = dd06v_wa
      dd06v_wa_a           = dd06v_wa_a
      got_state            = got_state
    tables
      dd16v_tab_n          = dd16v_tab
      dd16v_tab_a          = dd16v_tab_a
    exceptions
      access_failure       = 1
      illegal_value        = 2
      others               = 3.
  if sy-subrc <> 0.
    messtext = text-005.
    replace '&' in messtext with sqltab.
    smi4> prid 'E' 'AD010' messtext '' '' ''.
    rc = 8. exit.
  endif.

  read table dd16v_tab with key fieldname = 'VARDATA'.
  if syst-subrc = 0.
    if uc = ' '. length = 2 * length. endif.
    dd16v_tab-leng = dd16v_tab-intlen = length.
    modify dd16v_tab index syst-tabix.
  else.
*   Field VARDATA not found
    messtext = text-001.
    replace '&' in messtext with sqltab.
    smi4> prid 'E' 'AD010' messtext '' '' ''.
    rc = 8. exit.
  endif.

* Generate Nametab
* Read technical settings
  tabtname = sqltab.
  call function 'DD_TABT_GET'
    exporting
      get_state           = 'M'
*     PRID                = 0
      tabl_name           = tabtname
*     TRACELEVEL          = 0
   importing
*     DD09L_WA_A          =
      dd09l_wa_n          = dd09l_wa
      got_state           = tabt_got_state
    exceptions
      illegal_value       = 1
      op_failure          = 2
      others              = 3.
  if sy-subrc <> 0 or tabt_got_state = ' '.
    str> prid text-002.
  endif.

* Transform Tablepool- or -cluster-sources to generate Nametab
  dd02v_wa-tabname = dd06v_wa-sqltab.
  if dd06v_wa-sqlclass = 'POOL'.
    dd02v_wa-tabclass = 'TPOOL'.
  elseif dd06v_wa-sqlclass = 'CLUSTER'.
    dd02v_wa-tabclass = 'TCLUST'.
  endif.
  dd03p_wa-tabname = dd06v_wa-sqltab.
  loop at dd16v_tab into dd16v_wa.
    if dd16v_wa-position = '0001' and dd16v_wa-keyflag = 'X' and
       dd16v_wa-datatype = 'CLNT'.
      dd02v_wa-clidep = 'X'.
    endif.
    move-corresponding dd16v_wa to dd03p_wa.
    if dd03p_wa-datatype = 'INT2'.
      dd03p_wa-outputlen = ( dd03p_wa-intlen + 1 ) * 2.
    else.
      dd03p_wa-outputlen = dd03p_wa-intlen.
    endif.
    append dd03p_wa to dd03p_tab.
  endloop.

* Generate Nametab
  call function 'DD_NTAB_GEN'
    exporting
      dd02v_wa             = dd02v_wa
      dd09l_wa             = dd09l_wa
*     INCL_ALIGN           = 'X'
*     DBSYSTEM             = ' '
*     UC_LEN               = '00'
*     NO_INCL_NAMED        = ' '
    importing
      x030l_wa             = x030l_wa
    tables
      dd03p_tab            = dd03p_tab
      dd08v_tab            = dd08v_tab
      x031l_tab            = x031l_tab
    exceptions
      wrong_datatype       = 1
      wrong_tabtype        = 2
      others               = 3.
  if sy-subrc <> 0.
    clear x030l_wa. refresh x031l_tab. clear x031l_tab.
    smi1> prid 'E' 'DT005' sqltab.
    rc = 8. exit.
  else.
    if settmst = 'X'.   "Set timestamp and uuid
      timestamp_new      = sy-datum.
      timestamp_new+8(6) = sy-uzeit.
      x030l_wa-crstamp  = timestamp_new.
      x030l_wa-abstamp  = timestamp_new.
      x030l_wa-dystamp  = timestamp_new.
      str> prid text-008.
    else.
      tabname = sqltab.
      call function 'DD_GET_NAMETAB_HEADER'
        exporting
*         STATUS           = 'A'
          tabname          = tabname
        importing
*         R_MODEFLAG       =
*         R_STATUS         =
          x030l_wa         = x030l_wa_old
        exceptions
          not_found        = 1
          others           = 2.
      if syst-subrc = 0.
        x030l_wa-crstamp  = x030l_wa_old-crstamp.
        x030l_wa-abstamp  = x030l_wa_old-abstamp.
        x030l_wa-dystamp  = x030l_wa_old-dystamp.
      endif.
    endif.
*   Set uuid
    call function 'SYSTEM_UUID_CREATE'
           importing
               uuid    = uuid
           exceptions
                others  = 0. "#EC FB_OLDED
    if syst-subrc = 0. x030l_wa-uuid = uuid. endif. "#EC FB_NORC
    perform set_ntab_version(saplsdnt) using x030l_wa.
    loop at dd16v_tab into dd16v_wa.
      read table dd03p_tab into dd03p_wa index syst-tabix.
      dd16v_wa-intlen = dd03p_wa-intlen.
      modify dd16v_tab from dd16v_wa.
    endloop.
  endif.

* Put Nametab and Sources
  call function 'DD_PUT_NAMETAB'
    exporting
*     MODEFLAG           = ' '
      status             = 'A'
      x030l_wa           = x030l_wa
*     TRTYPE             = ' '
*     NO_INACT_DEL       = ' '
    importing
      r_subrc            = ntab_rc
    tables
      x031l_tab          = x031l_tab
    exceptions
      write_error        = 1
      others             = 2.
  if sy-subrc <> 0 or ntab_rc > 4.
    smi4> prid 'E' 'AD010' text-006 '' '' ''.
    rc = 8. exit.
  else.
    call function 'DD_SQLT_PUT'
      exporting
        dd06v_wa                  = dd06v_wa
        prid                      = prid
        put_state                 = 'A'
        sqlt_name                 = sqltab
*       CTRL_SQLT_PUT             = 'XX'
*       TRACELEVEL                = 0
      tables
        dd16v_tab                 = dd16v_tab
      exceptions
        db_access_failure         = 1
        illegal_value             = 2
        object_inconsistent       = 3
        others                    = 4.
    if sy-subrc <> 0.
      smi4> prid 'E' 'AD010' text-007 '' '' ''.
      rc = 8. exit.
    endif.
  endif.

* Table is correct now, so cnv-entry can be deleted
  delete from ddtpoolcnv where tabname  = sqltab
                         and   src_ntab_o = 'Y'.
  level_add> prid.
  if syst-subrc = 0.
    messtext = text-012.
    str> prid messtext.
  else.
    messtext = text-013.
    str> prid messtext.
  endif.
  level_sub> prid.

  messtext = text-009.
  replace '&' in messtext with length.
  str> prid messtext.

endform.

*&---------------------------------------------------------------------*
*&      Form  LOG_HANDLE
*&---------------------------------------------------------------------*
*       Opens and closes log
*----------------------------------------------------------------------*
*  -->OPEN    : Open log if content = 'X', otherwise close log
*  <--RC      : Returncode of log-tail-writing
*  -->FILE    : 'X', in case of file-logging
*  -->DATABASE: 'X', in case of database-logging
*  <--LOGNAME : logname
*  <--PRID    : ID of log-writer
*----------------------------------------------------------------------*
form log_handle using open file database logname prid rc.

  define_table par_tab ddpropval 0.
  data device(1).

  if open = 'X'.
    if file     = 'X'. device = 'F'. endif.
    if database = 'X'. device = 'T'. endif.

    log_open> device 'N' '1' 'set_style' logname ' '
              logname prid.
    prog_header> par_tab prid 'RATPONTC'.
  else.
    clear rc.
    prog_tail> prid 'RATPONTC' rc 'X'.
  endif.

endform.                    " LOG_HANDLE


*-Main-program---------------------------------------------------------*
AT SELECTION-SCREEN.
  if length <= 0.
    message 'Ungültige Länge (Siehe Hinweis 686357)'(014) type 'E'. "Invalid length (See note 686357)
   endif.

您可以使用 SE38 执行报告 RATPONTC,输入表池名称 = DVPOOLTEXT,长度 = 8192 并选择选项"长度来自 unicode 系统",然后执行。

之后,字段 VARDATA 的长度应更改为 8192。

之后,通过 Utilities->Database Object-> Check 检查数据库对象:

确保数据库对象与运行时对象保持一致,如上所述。另请通过"实用程序"->"运行时对象"->"检查"检查运行时对象是否与 SE11 定义一致,并确保运行时对象也一致:

该解决方案也适用于其他表池。

总结

对于所有 DB2 数据库(DB2、DB4、DB6),从 Unicode 系统本身的数据库中表的定义中获取字段 VARDATA 的正确长度:"SE11 ->(显示表) -> Utilities -> Database Object -> 显示"。对于所有其他数据库系统,请从下表中获取正确的长度:

Table pool Length
ATAB 904
DVPOOLTEXT 8192
GLSP 800
GLTP 2000
KAPOL 36

这些是 Unicode 系统的有效长度。因此,在执行程序 RATPONTC 之前,必须选中复选框,指定它是 Unicode 系统的长度。这适用于所有数据库。不要更改报告的剩余参数。使用 F8 执行程序。然后请通过"SE11 ->(显示表) -> Utilities -> Database Object -> Check"检查结果。不应该再显示不一致的情况。

参考链接:

  • SAP Note 2172320
  • SAP Note 686357
相关推荐
用户685453759776913 分钟前
同步成本换并行度:多线程、协程、分片、MapReduce 怎么选才不踩坑
后端
javaTodo21 分钟前
Claude Code 记忆机制详解:从 CLAUDE.md 到 Auto Memory,六层体系全拆解
后端
LSTM9742 分钟前
使用 C# 和 Spire.PDF 从 HTML 模板生成 PDF 的实用指南
后端
JaguarJack1 小时前
为什么 PHP 闭包要加 static?
后端·php·服务端
BingoGo1 小时前
为什么 PHP 闭包要加 static?
后端
是糖糖啊1 小时前
OpenClaw 从零到一实战指南(飞书接入)
前端·人工智能·后端
百度Geek说1 小时前
基于Spark的配置化离线反作弊系统
后端
Java编程爱好者2 小时前
虚拟线程深度解析:轻量并发编程的未来趋势
后端
苏三说技术2 小时前
Spring AI 和 LangChain4j ,哪个更好?
后端