当前位置: 首页 > news >正文

SAP自建表日志

文章目录

    • 1.在表里加上日志记录字段
      • 1.1 加入日志结构
      • 1.2 在代码中调用记录日志通用函数
      • 1.3 在SM30里面记录日志
      • 1.4 缺点
      • 1.5 优点
    • 2.表技术设置-日志数据更改
      • 2.1 RZ10或者RZ11修改系统参数
      • 2.2 设置表的属性
      • 2.3 查询日志
      • 2.4 缺点
      • 2.5 优点
    • 3 SCDO文档对象
      • 3.1 勾选相应字段-数据元素-更改文档
      • 3.2 SCDO创建对象,生成日志函数
      • 3.3 调用日志函数
        • 3.3.1 表格维护生成器调用日志函数
        • 3.3.2 非维护程序中调用日志函数
      • 3.4 查询日志
      • 3.5 缺点
      • 3.6 优点
    • 4.SE16N表数据更改日志
      • 4.1 使用要点
      • 4.2 缺点
      • 4.3 优点

1.在表里加上日志记录字段

如下所示,在表里新增一个结构,记录创建和修改日志

1.1 加入日志结构

在这里插入图片描述

1.2 在代码中调用记录日志通用函数

在代码中调用以下通用函数记录日志:
FUNCTION zbcfm_fill_log2.
*“----------------------------------------------------------------------
"“本地接口:
*” IMPORTING
*” VALUE(IV_UPDKZ) OPTIONAL
*" CHANGING
*" REFERENCE(CS_DATA)
*"----------------------------------------------------------------------

FIELD-SYMBOLS:<fs_f> TYPE any.
DATA:lv_updkz TYPE c.
DATA:lt_callstack TYPE abap_callstack.
DATA:lv_repid TYPE char100.

"如果判断是自定义程序调用(函数除外),如果是则取SY-CPROG
"不是则判断是函数调用还是report调用
IF sy-cprog+0(1) = ‘Z’.
lv_repid = sy-cprog.
ELSE.
"获取调用程序名称
CALL FUNCTION ‘SYSTEM_CALLSTACK’
IMPORTING
callstack = lt_callstack.

READ TABLE lt_callstack TRANSPORTING NO FIELDS WITH KEY flag_system = ‘X’ .
IF sy-subrc = 0.
"函数调用
lv_repid = VALUE #( lt_callstack[ 2 ]-blockname OPTIONAL ).
ELSE.
"report调用
lv_repid = VALUE #( lt_callstack[ 2 ]-mainprogram OPTIONAL ).
ENDIF.
ENDIF.

IF lv_repid IS INITIAL.
lv_repid = sy-repid.
ENDIF.

IF iv_updkz IS INITIAL.
ASSIGN COMPONENT ‘CRDAT’ OF STRUCTURE cs_data TO <fs_f>.
IF <fs_f> IS ASSIGNED.
IF <fs_f> = ‘00000000’.
lv_updkz = ‘I’.
ELSE.
lv_updkz = ‘U’.
ENDIF.
UNASSIGN:<fs_f>.
ENDIF.
ELSE.
lv_updkz = iv_updkz.
ENDIF.

CASE lv_updkz.
WHEN ‘I’."插入
ASSIGN COMPONENT ‘CRDAT’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-datum.
ENDIF.
ASSIGN COMPONENT ‘CRTIM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uzeit.
ENDIF.
ASSIGN COMPONENT ‘CRNAM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uname.
ENDIF.
ASSIGN COMPONENT ‘CRPGM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = lv_repid.
ENDIF.
WHEN ‘U’."更新
ASSIGN COMPONENT ‘UPDAT’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-datum.
ENDIF.
ASSIGN COMPONENT ‘UPTIM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uzeit.
ENDIF.
ASSIGN COMPONENT ‘UPNAM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uname.
ENDIF.
ASSIGN COMPONENT ‘LCDAT’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-datum.
ENDIF.
ASSIGN COMPONENT ‘LCTIM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uzeit.
ENDIF.
ASSIGN COMPONENT ‘LCNAM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = sy-uname.
ENDIF.
ASSIGN COMPONENT ‘LCPGM’ OF STRUCTURE cs_data TO <fs_f>.
IF sy-subrc = 0.
<fs_f> = lv_repid.
ENDIF.
ENDCASE.

ASSIGN COMPONENT ‘UPPGM’ OF STRUCTURE cs_data TO FIELD-SYMBOL(<fs_uppgm>).
IF <fs_uppgm> IS ASSIGNED.
<fs_uppgm> = lv_repid."sy-tcode.
ENDIF.

ENDFUNCTION.

1.3 在SM30里面记录日志

可参考本人这篇博文,地址:https://blog.csdn.net/HAND_YS/article/details/130338370?spm=1001.2014.3001.5502

1.4 缺点

此种方式只能查询修改与创建日期、时间、账号,无法查询哪些字段被修改。同时数据删除将没有日志。

1.5 优点

简单易用

2.表技术设置-日志数据更改

此种方式是基于表的日志,只要表里任何一个字段有修改,或者整条记录的删除、新增都会有对应的一条完整的记录,而不是多个字段修改多条记录

2.1 RZ10或者RZ11修改系统参数

TCODE:RZ10/RZ11
修改参数
rec/client = 300 (代表指定client要启用日志记录)
rec/client = all (代表所有客户端启用)
rec/client = off (不启用日志)
RZ10需要重启系统才能生效,且永久生效
RZ11当即生效,但是下次重启系统该参数将不会生效

2.2 设置表的属性

注意交付类为C,不能为A
在这里插入图片描述
点击技术设置
在这里插入图片描述
勾选“日志更改”
在这里插入图片描述

2.3 查询日志

无论是通过SM30手工前台维护,还是自定义代码进行增删改,均会记录日志到表DBTABLOG。
使用事务代码SCU3查询日志
在这里插入图片描述
日志效果如下
在这里插入图片描述

2.4 缺点

记录日志数据量会很大

2.5 优点

相比按照字段级别的日志数据量会少一些。假如修改数据,会有新数据和旧数据的对比。删除数据,也能看到操作记录

3 SCDO文档对象

此种方式是基于字段级别的日志,每个字段修改均会有一条记录

3.1 勾选相应字段-数据元素-更改文档

以下2个字段启用日志
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 SCDO创建对象,生成日志函数

事务代码SCDO
在这里插入图片描述
输入文本、表名,按照情况勾选表名后的选项,比如“内部表”选项:当勾选上则每次处理多条数据,生成的日志函数里包含CHANGEDOCUMENT_MULTIPLE_CASE子函数。不勾上则处理单条数据,生成的日志函数里包含CHANGEDOCUMENT_SINGLE_CASE的子函数。本例处理单条数据,则不勾选“内部表”
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
输入函数组名称(不需要事先创建)
在这里插入图片描述
在这里插入图片描述
此时会出现需要创建的清单,最后点击激活按钮
在这里插入图片描述
激活成功,即日志相应的对象已经生成
在这里插入图片描述

3.3 调用日志函数

3.3.1 表格维护生成器调用日志函数

在这里插入图片描述
以下代码为固定代码(如果SCDO维护时表后面的选项改变了,则需要调整以下代码,一般保持空选项即可),直接复制过去即可。以下代码会引用日志对象的2个INCLUDE文件,调用系统自动生成的FORM记录日志。
----------------------------------------------------------------------
***INCLUDE LZZTEST002F01.
----------------------------------------------------------------------
&---------------------------------------------------------------------
*& Form BEFORE_SAVE
&---------------------------------------------------------------------
& text
&---------------------------------------------------------------------
& --> p1 text
& <-- p2 text
&---------------------------------------------------------------------
FORM before_save .
TYPES: BEGIN OF ty_tcdrp,
object TYPE cdobjectcl,
reportname TYPE cdreport,
END OF ty_tcdrp,
BEGIN OF ty_view_tab,
object TYPE cdobjectcl,
tabname TYPE cdtabname,
END OF ty_view_tab.
DATA: lt_ptab TYPE STANDARD TABLE OF string,
lv_prog TYPE string,
lv_mess TYPE string,
lv_sid TYPE string,
lt_obj TYPE STANDARD TABLE OF ty_view_tab,
lt_tcdrp TYPE STANDARD TABLE OF ty_tcdrp,
lv_fugn TYPE funct_pool,
lv_table TYPE cdtabname,
lv_namesfunc TYPE namespace,
lv_funcgroup TYPE progname,
lv_namesprog TYPE namespace,
lv_program TYPE progname,
lrt_tabname TYPE RANGE OF tabname,
lt_dd26v TYPE TABLE OF dd26v,
lv_object TYPE cdobjectcl.
" Get tabnames
" DD: Interface for reading a view from the ABAP/4 Dictionary
CALL FUNCTION ‘DDIF_VIEW_GET’
EXPORTING
name = vim_view_name
TABLES
dd26v_tab = lt_dd26v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc IS NOT INITIAL.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
IF lt_dd26v IS INITIAL.
APPEND INITIAL LINE TO lrt_tabname ASSIGNING FIELD-SYMBOL(<lrs_tabname>).
<lrs_tabname>-sign = ‘I’.
<lrs_tabname>-option = ‘EQ’.
<lrs_tabname>-low = vim_view_name.
ELSE.
SORT lt_dd26v BY tabname.
DELETE ADJACENT DUPLICATES FROM lt_dd26v COMPARING tabname.
"
-
LOOP AT lt_dd26v INTO DATA(ls_dd26v).
APPEND INITIAL LINE TO lrt_tabname ASSIGNING <lrs_tabname>.
<lrs_tabname>-sign = ‘I’.
<lrs_tabname>-option = ‘EQ’.
<lrs_tabname>-low = ls_dd26v-tabname.
ENDLOOP.
ENDIF.
" Objects for change document creation
SELECT object tabname
FROM tcdob
INTO TABLE lt_obj
WHERE tabname IN lrt_tabname
##WARN_OK.
IF sy-subrc IS NOT INITIAL.
" No change document objects found
MESSAGE i899(cd).
RETURN.
ENDIF.
" Information on Include Reports Generated by RSSCD000
SELECT object reportname
FROM tcdrp
INTO TABLE lt_tcdrp
FOR ALL ENTRIES IN lt_obj
WHERE object EQ lt_obj-object
##WARN_OK.
IF sy-subrc IS NOT INITIAL.
" Update program does not yet exist
MESSAGE i446(m2).
RETURN.
ENDIF.
" View Directory
SELECT SINGLE area
FROM tvdir
INTO lv_fugn
WHERE tabname EQ vim_view_name.
"
-
LOOP AT lt_obj ASSIGNING FIELD-SYMBOL(<ls_obj>).
READ TABLE lt_tcdrp ASSIGNING FIELD-SYMBOL(<ls_tcdrp>)
WITH KEY object = <ls_obj>-object.
IF sy-subrc IS NOT INITIAL.
CONTINUE.
ENDIF.
" Split namespace
CLEAR: lv_namesprog, lv_program.
lv_program = <ls_tcdrp>-reportname.
CALL FUNCTION ‘RS_NAME_SPLIT_NAMESPACE’
EXPORTING
name_with_namespace = lv_program
IMPORTING
namespace = lv_namesprog
name_without_namespace = lv_program
EXCEPTIONS
delimiter_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
lv_program = <ls_tcdrp>-reportname.
ENDIF.
CLEAR: lv_namesfunc, lv_funcgroup.
lv_funcgroup = lv_fugn.
CALL FUNCTION ‘RS_NAME_SPLIT_NAMESPACE’
EXPORTING
name_with_namespace = lv_funcgroup
IMPORTING
namespace = lv_namesfunc
name_without_namespace = lv_funcgroup
EXCEPTIONS
delimiter_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
lv_funcgroup = lv_fugn.
ENDIF.
" Namespace conversion
lv_object = <ls_obj>-object.
IF lv_object(1) = ‘/’.
SHIFT lv_object LEFT DELETING LEADING ‘/’.
REPLACE FIRST OCCURRENCE OF ‘/’ IN lv_object WITH ‘'.
ENDIF.
lv_table = <ls_obj>-tabname.
IF lv_table(1) = ‘/’.
SHIFT lv_table LEFT DELETING LEADING ‘/’.
REPLACE FIRST OCCURRENCE OF ‘/’ IN lv_table WITH '
’.
ENDIF.
" Subroutine pool
APPEND ##NO_TEXT:
PROGRAM SUBPOOL. TO lt_ptab,
INCLUDE && lv_namesprog && F && lv_program && CDT. TO lt_ptab,
INCLUDE && lv_namesprog && F && lv_program && CDC. TO lt_ptab,
FORM frm_process. TO lt_ptab,
TYPES: BEGIN OF total. TO lt_ptab,
INCLUDE STRUCTURE && vim_view_name && . TO lt_ptab,
INCLUDE STRUCTURE vimflagtab. TO lt_ptab,
TYPES: END OF total. TO lt_ptab,
FIELD-SYMBOLS: <fs_total> TYPE ANY TABLE, TO lt_ptab,
<fs_total_wa> TYPE total, TO lt_ptab,
<fs_x_namtab> TYPE ANY TABLE, TO lt_ptab,
<fs_x_namtab_wa> TYPE vimnamtab, TO lt_ptab,
<fs_field> TYPE any. TO lt_ptab,
DATA: lv_tabname(40) TYPE c VALUE '( && lv_namesfunc && SAPL && lv_funcgroup && )TOTAL[]', TO lt_ptab,
lv_cond_line TYPE string, TO lt_ptab,
lv_cond_line2 TYPE string. TO lt_ptab,
ASSIGN (lv_tabname) TO <fs_total>. TO lt_ptab,
LOOP AT <fs_total> ASSIGNING <fs_total_wa> CASTING. TO lt_ptab,
CASE <fs_total_wa>-action. TO lt_ptab,
WHEN 'U'. " Update TO lt_ptab,
lv_tabname = '( && lv_namesfunc && SAPL && lv_funcgroup && )X_NAMTAB[]'. TO lt_ptab,
ASSIGN (lv_tabname) TO <fs_x_namtab>. TO lt_ptab,
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|. TO lt_ptab,
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2). TO lt_ptab,
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
lv_cond_line = lv_cond_line && |AND | && TO lt_ptab,
<fs_x_namtab_wa>-viewfield && | EQ '| && <fs_field> && |' |. TO lt_ptab,
objectid = objectid && <fs_field>. TO lt_ptab,
UNASSIGN <fs_field>. TO lt_ptab,
ENDIF. TO lt_ptab,
ENDLOOP. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
SHIFT lv_cond_line LEFT BY 3 PLACES. TO lt_ptab,
SELECT SINGLE * TO lt_ptab,
FROM && <ls_obj>-tabname TO lt_ptab,
INTO * && <ls_obj>-tabname TO lt_ptab,
WHERE (lv_cond_line). TO lt_ptab,
MOVE-CORRESPONDING <fs_total_wa> TO && <ls_obj>-tabname && . TO lt_ptab,
objectid = objectid. TO lt_ptab,
tcode = sy-tcode. TO lt_ptab,
udate = sy-datum. TO lt_ptab,
utime = sy-uzeit. TO lt_ptab,
username = sy-uname. TO lt_ptab,
cdoc_upd_object = 'U'. TO lt_ptab,
upd_ && lv_table && = 'U'. TO lt_ptab,
PERFORM cd_call_ && lv_object && . TO lt_ptab,
ENDIF. TO lt_ptab,
WHEN 'N'. " New TO lt_ptab,
lv_tabname = '( && lv_namesfunc && SAPL && lv_funcgroup && )X_NAMTAB[]'. TO lt_ptab,
ASSIGN (lv_tabname) TO <fs_x_namtab>. TO lt_ptab,
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|. TO lt_ptab,
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2). TO lt_ptab,
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
objectid = objectid && <fs_field>. TO lt_ptab,
UNASSIGN <fs_field>. TO lt_ptab,
ENDIF. TO lt_ptab,
ENDLOOP. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
MOVE-CORRESPONDING <fs_total_wa> TO && <ls_obj>-tabname && . TO lt_ptab,
objectid = objectid. TO lt_ptab,
tcode = sy-tcode. TO lt_ptab,
udate = sy-datum. TO lt_ptab,
utime = sy-uzeit. TO lt_ptab,
username = sy-uname. TO lt_ptab,
cdoc_upd_object = 'I'. TO lt_ptab,
upd_ && lv_table && = 'I'. TO lt_ptab,
PERFORM cd_call_ && lv_object && . TO lt_ptab,
ENDIF. TO lt_ptab,
WHEN 'D'. " Delete TO lt_ptab,
lv_tabname = '( && lv_namesfunc && SAPL && lv_funcgroup && )X_NAMTAB[]'. TO lt_ptab,
ASSIGN (lv_tabname) TO <fs_x_namtab>. TO lt_ptab,
lv_cond_line2 = |keyflag EQ 'X' AND viewfield NE 'MANDT'|. TO lt_ptab,
LOOP AT <fs_x_namtab> ASSIGNING <fs_x_namtab_wa> WHERE (lv_cond_line2). TO lt_ptab,
ASSIGN COMPONENT <fs_x_namtab_wa>-viewfield OF STRUCTURE <fs_total_wa> TO <fs_field>. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
objectid = objectid && <fs_field>. TO lt_ptab,
UNASSIGN <fs_field>. TO lt_ptab,
ENDIF. TO lt_ptab,
ENDLOOP. TO lt_ptab,
IF sy-subrc IS INITIAL. TO lt_ptab,
MOVE-CORRESPONDING <fs_total_wa> TO * && <ls_obj>-tabname && . TO lt_ptab,
objectid = objectid. TO lt_ptab,
tcode = sy-tcode. TO lt_ptab,
udate = sy-datum. TO lt_ptab,
utime = sy-uzeit. TO lt_ptab,
username = sy-uname. TO lt_ptab,
cdoc_upd_object = 'D'. TO lt_ptab,
upd_ && lv_table && = 'D'. TO lt_ptab,
PERFORM cd_call_ && lv_object && . TO lt_ptab,
ENDIF. TO lt_ptab,
ENDCASE. TO lt_ptab,
CLEAR: lv_cond_line, lv_cond_line2, objectid, && <ls_obj>-tabname && , * && <ls_obj>-tabname && . TO lt_ptab,
ENDLOOP. TO lt_ptab,
ENDFORM. TO lt_ptab.
"
-
GENERATE SUBROUTINE POOL lt_ptab NAME lv_prog
MESSAGE lv_mess
SHORTDUMP-ID lv_sid.
IF sy-subrc = 0.
PERFORM (‘FRM_PROCESS’) IN PROGRAM (lv_prog) IF FOUND.
ELSEIF sy-subrc = 4.
MESSAGE lv_mess TYPE ‘I’.
ELSEIF sy-subrc = 8.
MESSAGE lv_sid TYPE ‘I’.
ENDIF.
CLEAR: lt_ptab.
ENDLOOP.
ENDFORM.
&---------------------------------------------------------------------
*& Form AFTER_SAVE
&---------------------------------------------------------------------
*& text
&---------------------------------------------------------------------
*& --> p1 text
*& <-- p2 text
&---------------------------------------------------------------------
FORM after_save .
COMMIT WORK AND WAIT.
ENDFORM.

3.3.2 非维护程序中调用日志函数

本例展示在REPORT程序中调用标准日志函数,实现修改、新增、删除的日志
代码如下:
&--------------------------------------------------------------------


  • Program Name : *
  • Program Title : *
  • Application :   *
  • Description : *
  • Func Spec ID : *
  • Requested by : *
  • Author : *
  • Req Date : *

  • MODIFICATIONS (latest entry at the top) *
  • ------------------------------------------------------------------- *
  • DATE NAME (COMPANY) DESCRIPTION TASK-NO *
  • ---- ---- --------- ----------- ------- *
  •                                                                 *
    

&--------------------------------------------------------------------

REPORT zys012 .

INCLUDE fzztest002_scdocdt.
INCLUDE fzztest002_scdocdc.

START-OF-SELECTION.

SELECT * FROM zztest002 INTO TABLE @DATA(lt_zztest002).

"修改数据
LOOP AT lt_zztest002 INTO DATA(ls_zztest002).
CLEAR:*zztest002,zztest002.
"旧数据
MOVE-CORRESPONDING ls_zztest002 TO *zztest002.
"新数据
MOVE-CORRESPONDING ls_zztest002 TO zztest002.
zztest002-text1_zztest002 = ‘118’.
zztest002-text2_zztest002 = ‘118’.
objectid = ls_zztest002-num.
PERFORM frm_call_zztest002_scdo USING ‘U’.
MODIFY zztest002 FROM zztest002.

ENDLOOP.

"新增数据
CLEAR:*zztest002,zztest002.
"新数据
zztest002-num = ‘29’.
zztest002-text1_zztest002 = ‘800’.
zztest002-text2_zztest002 = ‘801’.
objectid = zztest002-num.
PERFORM frm_call_zztest002_scdo USING ‘I’.

MODIFY zztest002 FROM zztest002.

"删除数据
CLEAR:*zztest002,zztest002.
"旧数据
*zztest002-num = ‘26’.
objectid = *zztest002-num.
PERFORM frm_call_zztest002_scdo USING ‘D’.

DELETE FROM zztest002 WHERE num = ‘26’…

&---------------------------------------------------------------------
*& Form frm_call_zztest002_scdo
&---------------------------------------------------------------------
*& text
&---------------------------------------------------------------------
*& --> LS_OLD_DATA
*& --> LS_NEW_DATA
*& --> P_
&---------------------------------------------------------------------
FORM frm_call_zztest002_scdo USING fu_flag TYPE cdpos-chngind.

cdoc_upd_object = fu_flag.
upd_zztest002 = fu_flag.
tcode = sy-tcode.
udate = sy-datum.
utime = sy-uzeit.
username = sy-uname.

PERFORM cd_call_zztest002_scdo.

COMMIT WORK AND WAIT.

ENDFORM.

3.4 查询日志

使用程序CHANGEDOCU_READ 查看更改日志
日志数据记录表 CDHDR、CDPOS

在这里插入图片描述
通过在SM30里面新增、修改、删除数据后,查询日志记录如下:
在这里插入图片描述

3.5 缺点

需要建立变更对象,同时在使用处调用日志函数,使用相对麻烦。同时是字段级别的日志,数据量会比较大。

3.6 优点

针对字段级别的日志,比较详细

4.SE16N表数据更改日志

4.1 使用要点

使用SE16N更改表数据时会记录更改日志。日志数据记录表 SE16N_CD_KEY(主表)、SE16N_CD_DATA(存历史数据)

4.2 缺点

SE16N权限较大,不能给普通用户使用,在权限方面需要控制

4.3 优点

简单易用。并且记录了历史数据。按照表级别记录日志。

相关文章:

SAP自建表日志

文章目录 1.在表里加上日志记录字段1.1 加入日志结构1.2 在代码中调用记录日志通用函数1.3 在SM30里面记录日志1.4 缺点1.5 优点 2.表技术设置-日志数据更改2.1 RZ10或者RZ11修改系统参数2.2 设置表的属性2.3 查询日志2.4 缺点2.5 优点 3 SCDO文档对象3.1 勾选相应字段-数据元素…...

ansible-kubeadm在线安装单masterk8s v1.19-v1.20版本

ansible可以安装的KS8版本如下&#xff1a; [rootk8s-master01 ~]# yum list kubectl --showduplicates | sort -r kubectl.x86_64 1.20.0-0 kubernetes kubectl.x86_64 1.20.0-0 …...

mongodb docker 及常用命令

MongoDB属于非关系型数据库&#xff0c;它是由C编写的分布式文档数据库。内部使用类似于Json的bson二进制格式。 中文手册 https://www.w3cschool.cn/mongodb/ 安装 https://www.mongodb.com/try/download/community 二进制安装可见另一篇&#xff1a; centos7 mongodb 4.0.28…...

最新版本mac版Idea 激活Jerbel实现热部署

1.环境准备 1.安装docker desktop 客户端创建本地服务 2.创建guid 3.随便准备一个正确格式的邮箱 2.具体操作 1.通过提供的镜像直接搭建本地服务 docker pull qierkang/golang-reverseproxy docker run -d -p 8888:8888 qierkang/golang-reverseproxy2.guid 通过如下网址直…...

基于Ubuntu22.04部署bcache模式ceph

作者&#xff1a;吴业亮 博客&#xff1a;wuyeliang.blog.csdn.net 将Bcache集成到Ceph OSD后端可以带来一些优点和潜在的缺点。以下是它们的一些方面&#xff1a; 优点&#xff1a; 提高性能&#xff1a;BCache作为SSD缓存设备&#xff0c;可以提供更快的数据读取和写入速度…...

根据URL批量下载文件并压缩成zip文件

根据url批量下载图片或者视频&#xff0c;只需要将图片的url和名称放到数组对象即可&#xff0c;例如&#xff1a; let fileArr [{fvUrl:https://image.xuboren.com/image/2023/07/26/1410829074764cdbaa4314a084eb749e.jpg,fvName: 图片名称},{fvUrl:https://image.xuboren.…...

机器学习笔记之优化算法(六)线搜索方法(步长角度;非精确搜索;Glodstein Condition)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索&#xff0c;Glodstein Condition] 引言回顾&#xff1a; Armijo Condition \text{Armijo Condition} Armijo Condition关于 Armijo Condition \text{Armijo Condition} Armijo Condition的弊端 Glodstein…...

Ant Design Pro 封装网络请求

可以直接在antdPro项目的app.tsx文件中对request进行运行时配置&#xff0c;并且该配置会直接透传到umi-request的全局配置。后续直接从umi中引入request或者useRequest直接使用&#xff0c;可以说是非常方便。文档可查看&#xff1a;umi.js 具体配置代码&#xff1a; import…...

命令模式——请求发送者与接收者解耦

1、简介 1.1、概述 在软件开发中&#xff0c;经常需要向某些对象发送请求&#xff08;调用其中的某个或某些方法&#xff09;&#xff0c;但是并不知道请求的接收者是谁&#xff0c;也不知道被请求的操作是哪个。此时&#xff0c;特别希望能够以一种松耦合的方式来设计软件&a…...

css 利用模糊属性 制作水滴

<style>.box {background-color: #111;height: 100vh;display: flex;justify-content: center;align-items: center;/* 对比度*/filter: contrast(20);}.drop {width: 150px;height: 159px;border-radius: 50%;background-color: #fff;position: absolute;/* 模糊 */filt…...

怎么才能提升自己工作能力?

表现最好的员工通常是获得加薪和工作晋升的人。您可以采取某些措施来提高您的工作绩效&#xff0c;并帮助您的主管将您视为他们最好的员工之一。在本文中&#xff0c;我们列出了 12 个技巧&#xff0c;可以立即提高您的工作绩效。 什么是工作绩效&#xff1f; 工作绩效是指您…...

Android Framework 之 Zygote

Android Zygote Android Zygote 是 Android 操作系统中一个关键的系统服务&#xff0c;它在系统启动时加载&#xff0c;为应用程序的运行提供了一种快速且资源高效的方式。 Zygote 的主要作用如下&#xff1a; 预加载共享库和类&#xff1a;Zygote 启动时&#xff0c;会预先加…...

二叉树的中序遍历 LeetCode热题100

题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 思路 递归&#xff0c;按左中右的顺序添加节点。 利用栈先进后出的特性模拟递归。 代码 /**递归写法* Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left…...

IOS + Appium自动化教程

前言 项目闲置下来了&#xff0c;终于抽空有时间搞自动化了&#xff0c;看了下网上的教程基本通篇都是android自动化的介绍 &#xff0c;ios自动化方面的内容网上简介的少之可怜。由于本人对ios自动化也是第一次做&#xff0c;甚至对苹果电脑的使用都不太熟悉&#xff0c;花了大…...

100个精选Python实战项目案例,在线无偿分享

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 随着 Python 语言的流行&#xff0c;越来越多的人加入到了 Python 的大家庭中。 为什么这么多人学 Python &#xff1f; 我要喊出那句话了&#xff1a;“人生苦短&#xff0c;我用 Python&#xff01;”&#xff0c; 正是…...

JSON语法

目录 一、JSON 语法规则 二、JSON 的两种结构&#xff1a; 三、JSON 名称/值对 JSON 值 JSON 数字 JSON 对象 JSON 数组 JSON 布尔值 JSON null 四、JSON 使用 JavaScript 语法 JSON 语法是 JavaScript 语法的子集。 一、JSON 语法规则 JSON 语法是 JavaScript 对象…...

PostMan+Jmeter+QTP工具介绍及安装

目录 一、PostMan介绍​编辑 二、下载安装 三、Postman与Jmeter的区别 一、开发语言区别&#xff1a; 二、使用范围区别&#xff1a; 三、使用区别&#xff1a; 四、Jmeter安装 附一个详细的Jmeter按照新手使用教程&#xff0c;感谢作者&#xff0c;亲测有效。 五、Jme…...

2023电赛E题视觉部分

该部分主要要完成正方形区域的识别&#xff0c;并返回对应的坐标&#xff0c;但是由于距离1m&#xff0c;过远。因此需要引入图像增强&#xff0c;下面代码完成基本流程测试&#xff0c;仅供参考&#xff1a; import sensor import image import time # 初始化摄像头 senso…...

算法工程师岗位面试必备,讲透深度学习面试题,详解人工智能生成式任务与AI大模型面试题

DeepLearning-Interview-Awesome-2024 算法工程师岗位面试必备&#xff0c;讲透深度学习面试题&#xff0c;详解人工智能生成式任务与AI大模型面试题 实时更新题解链接&#xff1a;https://github.com/315386775/DeepLearing-Interview-Awesome-2024 记得点个关注&#xff0…...

JVM基础篇-虚拟机栈

JVM基础篇-虚拟机栈 定义 Java Virtual Machine Stacks &#xff08;Java 虚拟机栈&#xff09; 每个线程运行时所需要的内存&#xff0c;称为虚拟机栈每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xff0c;对应着每次方法调用时所占用的内存每个线程只能有一个活动…...

KepwareEX配置API REST接口

服务端Kepware设置 API允许连接设置 创建通道 请求地址(POST)&#xff1a; https://<主机名_或_ip>:<端口>/config/v1/project/channels 以下示例使用postman工具访问API创建了一个名为Channel1 的通道&#xff0c;其使用在本地主机运行的服务器中的Simulator …...

【python】python求解矩阵的转置(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…...

Mr. Cappuccino的第56杯咖啡——Mybatis拦截器

Mybatis拦截器 概述应用场景项目结构实现分页查询其它拦截器的使用 概述 Mybatis允许使用者在映射语句执行过程中的某一些指定的节点进行拦截调用&#xff0c;通过织入拦截器&#xff0c;在不同节点修改一些执行过程中的关键属性&#xff0c;从而影响SQL的生成、执行和返回结果…...

容器化安装环境EFK搭建

容器化安装环境 Docker中安装并启动ElasticSearch 前置配置 第一步&#xff1a;在宿主机上执行echo “net.ipv4.ip_forward1” >>/usr/lib/sysctl.d/00-system.conf 2.第二步&#xff1a;重启network和docker服务 [rootlocalhost /]# systemctl restart network &&…...

基于 Debian GNU/Linux 12 “书虫 “的Neptune 8.0 “Juna “来了

导读Neptune Linux 发行版背后的团队发布了 Neptune 8.0&#xff0c;作为这个基于 Debian 的 GNU/Linux 发行版的重大更新&#xff0c;它围绕最新的 KDE Plasma 桌面环境构建。 Neptune 8.0 被命名为 “Juna”&#xff0c;是在Neptune 7.5 发布 11 个月后发布的&#xff0c;也是…...

GDAL C++ API 学习之路 (4) Spatial Reference System篇 OGRSpatialReference类

class OGRSpatialReference #include <ogr_spatialref.h> OGRSpatialReference 是 GDAL/OGR 库中的一个重要类&#xff0c;用于管理和操作地理空间数据的空间参考系统&#xff08;Spatial Reference System&#xff0c;SRS&#xff09;。它提供了一系列功能&…...

RS232转Profinet网关rs232转网口需要如何设置

大家好&#xff0c;今天我要给大家带来一个很有意思的案例分享。你们猜猜&#xff0c;这回我们要用捷米的一款神奇的网关JM-RS485/232-PN做什么呢&#xff1f;没错&#xff0c;我们要把一台扫码枪设备通过这个RS232转PROFINET网关&#xff0c;接入到一台西门子S7-1200PLC的Prof…...

LaTex的下载与安装超详细windows版

1.LaTex的下载 &#xff08;texlive下载TexStudio下载&#xff09; &#xff08;1&#xff09;texlive下载&#xff1a; 这里清华镜像下载 &#xff08;2&#xff09;TexStudio下载&#xff1a; 点这里下载镜像 可以根据不同的系统选择不同的版本 2 .LaTex的安装 &#…...

MySQL | 存储过程快速入门

文章目录 一、概述1.1 MySQL存储过程和函数的概念1.2 优势和适用场景 二、存储过程基础2.1 存储过程与传统SQL查询的区别2.2 创建和调用存储过程创建存储过程调用存储过程 2.3 参数传递与返回值创建带有输出参数的存储过程调用带有输出参数的存储过程 2.4 流程控制语句IF语句WH…...

C# 图表控件库 ScottPlot

推荐使用ScottPlot原因&#xff1a; 1.图形界面简洁&#xff0c;样式丰富 2.代码较少 3.官方提供多种实例源码&#xff0c;并可以直接通过图形界面查看&#xff0c;便于快速开发 Github源码链接&#xff1a;https://github.com/ScottPlot/ScottPlot 官网WindowFrom Demo实例…...