问题描述
在 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
在我的系统中,会发现表池 DVPOOLTEXT
的 VARDATA
的字段长度为 16384,如下图:
可以看到,数据库对象的 VARDATA
字段长度为 16384 ,而运行时对象的 VARDATA
字段长度为 8192。所以问题是字典和运行时对象的字段 VARDATA
的长度是数据库对象的两倍。由于数据库对象和运行时对象不一致,出现 dump DBIF_RSQL_SQL_ERROR 。同样的问题也可能发生在其他表池上,例如 ATAB
、KAPOL
、GSLP
、GLSP
或 GLTP
等。
原因
程序 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