Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Abap 修改常规结构化表中的某些BSEG字段_Abap_Opensql_Internal Tables - Fatal编程技术网

Abap 修改常规结构化表中的某些BSEG字段

Abap 修改常规结构化表中的某些BSEG字段,abap,opensql,internal-tables,Abap,Opensql,Internal Tables,我尝试使用以下方法: update bseg from zbseg 其中表的长度不同(ZBSEG是BSEG的简化版本) 整个想法是,BSEG只是一个例子,我有一个循环,其中所有集群表都将被迭代,所以所有内容都应该是动态的 集群中的表数据被缩减为仅几个字段,并复制到透明表中(新的透明表中的数据字典具有主键+仅少数集群字段),之后,数据库中的数据将被修改并通过UPDATE复制回集群 update bseg from zbseg 此语句从ZBSEG更新字段值,但对于其余字段,将不保留旧值,而是放入

我尝试使用以下方法:

update bseg from zbseg
其中表的长度不同(
ZBSEG
BSEG
的简化版本)

整个想法是,
BSEG
只是一个例子,我有一个循环,其中所有集群表都将被迭代,所以所有内容都应该是动态的

集群中的表数据被缩减为仅几个字段,并复制到透明表中(新的透明表中的数据字典具有主键+仅少数集群字段),之后,数据库中的数据将被修改并通过
UPDATE
复制回集群

update bseg from zbseg
此语句从
ZBSEG
更新字段值,但对于其余字段,将不保留旧值,而是放入初始值

我甚至试过:

SELECT *
FROM bseg
INTO TABLE gt_bseg.

SELECT mandt bukrs belnr gjahr buzei buzid augdt
FROM zbseg
INTO CORRESPONDING FIELDS OF TABLE gt_bseg.
但它仍然与zbseg中未考虑的字段重叠

任何只更新从
ZBSEG
提取的特定范围的字段的语句,而不接触其他
BSEG
字段


我认为您需要从zbseg获取具有限制的记录,因为将存在数百万条记录,然后从bseg中逐个获取并更新记录,然后从zbseg中删除或更新其标志以提高性能

tables: BSEG, ZBSEG.

data: GT_ZBSEG like ZBSEG occurs 1 with header line,
      GS_BSEG type BSEG.

select *
into table GT_ZBSEG up to 1000 rows
from ZBSEG.

check SY-SUBRC is initial.
check SY-DBCNT is not initial.

loop at GT_ZBSEG.
  select single * from BSEG into GS_BSEG
  where BSEG~MANDT = GT_ZBSEG-MANDT
    and BSEG~BUKRS = GT_ZBSEG-BUKRS
    and BSEG~BELNR = GT_ZBSEG-BELNR
    and BSEG~GJAHR = GT_ZBSEG-GJAHR
    and BSEG~BUZEI = GT_ZBSEG-BUZEI.
  if SY-SUBRC ne 0.
    message E208(00) with 'Record not found!'.
  endif.
  if GS_BSEG-BUZID ne GT_ZBSEG-BUZID
  or GS_BSEG-AUGDT ne GT_ZBSEG-AUGDT.
    move-corresponding GT_ZBSEG to GS_BSEG.
    update BSEG from GS_BSEG.
  endif.
  " delete same records and transfered
  delete ZBSEG from GT_ZBSEG.
endloop.

您可以尝试使用MODIFY语句来更新表

另一种方法是使用cl\u abap\u typedescr获取每个表的字段,并比较它们以进行更新

下面是一个如何获取字段的示例

DATA : ref_table_des TYPE REF TO cl_abap_structdescr,
       columns TYPE abap_compdescr_tab.

ref_table_des ?= cl_abap_typedescr=>describe_by_data( struc ).
columns = ref_table_des->components[].

下面是一段代码,您可以用于您的任务。它基于动态更新语句,只允许更新某些字段:

DATA: handle      TYPE REF TO data,
      lref_struct TYPE REF TO cl_abap_structdescr,
      source      TYPE string,
      columns     TYPE string,
      keys        TYPE string,
      cond        TYPE string,
      sets        TYPE string.

SELECT tabname FROM dd02l INTO TABLE @DATA(clusters) WHERE tabclass = 'CLUSTER'.

LOOP AT clusters ASSIGNING FIELD-SYMBOL(<cluster>).
  lref_struct ?= cl_abap_structdescr=>describe_by_name( <cluster>-tabname ).
  source = 'Z' && <cluster>-tabname. " name of your ZBSEG-like table
* get key fields
  DATA(key_fields) = VALUE ddfields( FOR line IN lref_struct->get_ddic_field_list( ) 
                                     WHERE ( keyflag NE space ) ( line ) ).
  lref_struct ?= cl_abap_structdescr=>describe_by_name( source ).
* get all fields from source reduced table
  DATA(fields) = VALUE ddfields( FOR line IN lref_struct->get_ddic_field_list( ) ( line ) ).

* filling SELECT fields and SET clause
  LOOP AT fields ASSIGNING FIELD-SYMBOL(<field>).
    AT FIRST.
      columns = <field>-fieldname.
      CONTINUE.
    ENDAT.
    CONCATENATE columns <field>-fieldname INTO columns SEPARATED BY `, `.
    IF NOT line_exists( key_fields[ fieldname = <field>-fieldname ] ).
      IF sets IS INITIAL.
        sets = <field>-fieldname && ` = @<fsym_wa>-` && <field>-fieldname.
      ELSE.
        sets = sets && `, ` && <field>-fieldname && ` = @<fsym_wa>-` && <field>-fieldname.
      ENDIF.
    ENDIF.
  ENDLOOP.

* filling key fields and conditions
  LOOP AT key_fields ASSIGNING <field>.
    AT FIRST.
      keys = <field>-fieldname.
      CONTINUE.
    ENDAT.
    CONCATENATE keys <field>-fieldname INTO keys SEPARATED BY `, `.
    IF cond IS INITIAL.
      cond = <field>-fieldname && ` = @<fsym_wa>-` && <field>-fieldname.
    ELSE.
      cond = cond && ` AND ` && <field>-fieldname && ` = @<fsym_wa>-` && <field>-fieldname.
    ENDIF.
  ENDLOOP.

* constructing reduced table type
  lref_struct ?= cl_abap_typedescr=>describe_by_name( source ).
  CREATE DATA handle TYPE HANDLE lref_struct.
  ASSIGN handle->*  TO FIELD-SYMBOL(<fsym_wa>).

* updating result cluster table
  SELECT (columns)
    FROM (source)
    INTO @<fsym_wa>.
  UPDATE (<cluster>-tabname)
  SET (sets)
  WHERE (cond).
  ENDSELECT.

ENDLOOP.
DATA:数据的句柄类型REF,
lref_结构类型参考至cl_abap_结构描述,
源类型字符串,
列类型字符串,
键类型字符串,
cond类型字符串,
设置类型字符串。
从dd02l中选择tabname到表@DATA(clusters),其中tabclass='CLUSTER'。
循环指定字段-SYMBOL()。
lref_struct?=cl_abap_structdescr=>按_名称(-tabname)描述_。
source='Z'&&-tabname。“类似ZBSEG的表的名称
*获取关键字段
数据(键字段)=值字段(用于lref结构->获取字段列表()中的行)
其中(键标志NE空格)(行))。
lref_struct?=cl_abap_structdescr=>按_名称(源)描述_。
*从源简化表中获取所有字段
数据(字段)=值ddfields(用于lref_struct->get_ddic_field_list()(行))中的行)。
*填充SELECT字段和SET子句
在指定字段-SYMBOL()的字段处循环。
一开始
columns=-fieldname。
继续。
恩达。
将columns-fieldname连接到由“,”分隔的列中。
如果不存在行(键字段[fieldname=-fieldname])。
如果设置为初始值。
设置=-fieldname&&`=@-`&&&-fieldname。
其他的
集合=集合&&`、`&&-fieldname&&`=@-`&&&-fieldname。
恩迪夫。
恩迪夫。
结束循环。
*填写关键字段和条件
在指定的关键点处循环。
一开始
keys=-fieldname。
继续。
恩达。
将keys-fieldname连接到由“,”分隔的键中。
如果cond是初始值。
cond=-fieldname&&`=@-`&&&-fieldname。
其他的
cond=cond&&`和`&&-fieldname&&`=@-`&&&-fieldname。
恩迪夫。
结束循环。
*构造约化表类型
lref_struct?=cl_abap_typedescr=>按名称描述(源)。
创建数据句柄类型handle lref_struct。
将句柄->*分配给字段-SYMBOL()。
*更新结果群集表
选择(列)
来源(来源)
进入@。
更新(-tabname)
一套(套)
何处(秒)。
结束选择。
结束循环。
这篇文章从DD02L中选择所有集群表,并假设每个目标集群表都有前缀为Z的精简DB表。例如,对于BSEGZBSETBSETZKONV


表由主键更新,主键必须包含在缩减表中。要更新的字段作为所有字段(不包括键字段)从缩减表中获取,因为主键禁止更新。

感谢回复mkysoft。但一切都是动态的,所以我无法通过主键访问它们。因此我必须做些事情我真的不喜欢循环中的循环,所以我将从第二个表中获取原始数据并只更新相应的字段。请看第一篇文章,我将在那里发布循环中的图片。谢谢!也许你可以找到带有FM BDL_DDIF_table_GET的关键字段并创建动态条件。另一方面,我认为使用本机带行哈希的sql是确定已更改行的好选项。然后循环使用它们。与@mkysoft一致,动态条件易于使用(
DATA-where-TYPE-string.where='BSEG~MANDT=GT_ZBSEG~MANDT AND…'。选择…where(where)
);更喜欢使用RTTI,如@AZn5ReD所解释的cl_abap_typedescr,而不是不受支持的功能模块,如(BDL_)DDIF_TABL_GET;关于本机SQL,通常不能在集群表(即BSEG)上使用,因为BSEG是真实数据库表(BSEG为RFBLG)的逻辑SAP特定“视图”。从(tabname_new)--->ZBSEG into-->ZBSEG结构为WHERE(LV_WHERE_COND)的字段符号。LV_WHERE_COND=(MANDT eq-MANDT和BELNR eq-BELNR和BUREG eq-BUREG和LFDNR eq-LFDNR)转储是由于以下原因引发的:对象不平坦(深层数据对象不支持当前语句)我也尝试过使用ZBSEG~MANDT=-MANDT,但没有成功。不要担心以前的错误。我修复了它!:)并且它工作得非常快。非常感谢mkysoft!!修改dbtab不允许更新单独的字段,如果您谈到修改itab,您应该给出完整的工作动态示例