从与 VALUE 内联构建的内部 table 更新数据库 table
Update DB table from internal table constructed inline with VALUE
我正在尝试同时更新包含多行的数据库 Table。
我只需要从内部 table.
更新名为 ESTADO 的字段
我不想在循环语句中这样做。
这是因为代码检查器工具和性能。
我试图找到一些关于新的 abap 语法的信息,我找到了一个内联语句来避免循环。
UPDATE ZBWEVATDOC61 FROM TABLE @( VALUE #(
FOR ls_doc61 IN it_doc61 WHERE ( cuv = ls_doc61-cuv And folio = l
s_doc61-folio and folio_interno = ls_doc61-folio_interno )
( VALUE #(
BASE ls_doc61
estado = ls_doc61-estado ) ) ) ) .
IF sy-subrc eq 0.
commit work AND WAIT.
ENDIF.
我尝试使用 WHERE 语句指定要更新的行,但不起作用
语句 UPDATE dbtab FROM TABLE itab
,无论 itab
是内部 table 是数据对象还是构造函数表达式 ("new syntax") 的结果,都需要 itab
与 dbtab
有相同结构的行,这意味着 dbtab
的所有列都将被更新,并且该语句没有其他更好的选择。
1) 批量更新给定行的给定列的唯一解决方案是这样的:
- 在要更新的 table 上创建一个 "database view",方法是仅 select 相关列 + select 您定义的行所需的列作为关键字段(列名称右侧的复选框),并选择访问权限 "read and change" 以便(至少)可以使用
UPDATE
。
- 在您的程序中,定义一个内部 table,其中的行类型类似于数据库视图。
- 使用
UPDATE dbtab FROM TABLE itab
更新数据库视图。键字段中定义的行将被 selected,非键列将被更新。
- 我在这里不讨论如何编写构造函数表达式 (
... @( VALUE #( ... ) )
),因为您认为它可以解决您的问题的假设是错误的。
ABAP 中有一些方法可以更新几列或几行,但不能同时更新:
- 2) 将给定列设置为固定值 - 在所有更新的行中,这些列将具有相同的值:
UPDATE dbtab SET col1 = value1 col2 = value2 ... \[WHERE ...\]
。您可以在循环内重复 UPDATE ... SET ...
以模仿批量更新。它将比通过数据库视图更新(案例 2)慢,我不确定它是否比案例 3 快或慢(可能取决于列数)。
- 3) 如果您可以确定
itab
在您不感兴趣的所有其他列中包含正确的值,您仍然可以考虑使用 UPDATE dbtab FROM TABLE itab
。您可以考虑防止并发更新(由其他程序 运行 并行或最终由另一个用户使用同一程序 运行)使用锁,以避免在 SELECT
之间进行一些更新以初始化内部 table 和 UPDATE
.
注意:我不明白你为什么说 LOOP 是 Code Inspector 和性能的问题。构造函数表达式(如您所说的 "new syntax" )用于避免中间变量,对于 better readability and to focus on final goal.
以下语法有效:
TYPES: ttcurr TYPE TABLE OF tcurr WITH EMPTY KEY.
SELECT ukurs, tcurr, gdatu
FROM tcurr
INTO TABLE @DATA(ltcurr)
UP TO 100 ROWS.
DATA(it_modified) = VALUE ttcurr( FOR ls_tcurr IN ltcurr ( ukurs = ls_tcurr-ukurs / 1000 tcurr = ls_tcurr-tcurr gdatu = ls_tcurr-gdatu ) ).
UPDATE tcurr FROM TABLE @(
VALUE ttcurr(
FOR ls_curr IN it_modified WHERE ( tcurr NE 'EUR' AND gdatu > '79989898' )
( ukurs = ls_curr-ukurs ) ) ).
BASE
在您的代码段中使用错误,当您用 table 表达式填充一些 itab 并希望保留其以前的内容时使用它,它只接受 itab 操作数。在我们的例子中,更新 dbtab 时可以省略它。
您不能在此语句中使用内联类型,也不能在 WHERE
.
中使用自动生成的变量 ls_doc61
进行比较
尝试将您的代码段更改为类似的内容:
TYPES: ttdoc TYPE TABLE OF ZBWEVATDOC61 WITH EMPTY KEY.
UPDATE ZBWEVATDOC61 FROM TABLE @(
VALUE ttdoc(
FOR ls_doc61 IN it_doc61 WHERE ( cuv = 'smth' AND folio = 'smth' AND folio_interno = 'smth' )
( estado = ls_doc61-estado ) ) ).
我正在尝试同时更新包含多行的数据库 Table。 我只需要从内部 table.
更新名为 ESTADO 的字段我不想在循环语句中这样做。 这是因为代码检查器工具和性能。
我试图找到一些关于新的 abap 语法的信息,我找到了一个内联语句来避免循环。
UPDATE ZBWEVATDOC61 FROM TABLE @( VALUE #(
FOR ls_doc61 IN it_doc61 WHERE ( cuv = ls_doc61-cuv And folio = l
s_doc61-folio and folio_interno = ls_doc61-folio_interno )
( VALUE #(
BASE ls_doc61
estado = ls_doc61-estado ) ) ) ) .
IF sy-subrc eq 0.
commit work AND WAIT.
ENDIF.
我尝试使用 WHERE 语句指定要更新的行,但不起作用
语句 UPDATE dbtab FROM TABLE itab
,无论 itab
是内部 table 是数据对象还是构造函数表达式 ("new syntax") 的结果,都需要 itab
与 dbtab
有相同结构的行,这意味着 dbtab
的所有列都将被更新,并且该语句没有其他更好的选择。
1) 批量更新给定行的给定列的唯一解决方案是这样的:
- 在要更新的 table 上创建一个 "database view",方法是仅 select 相关列 + select 您定义的行所需的列作为关键字段(列名称右侧的复选框),并选择访问权限 "read and change" 以便(至少)可以使用
UPDATE
。 - 在您的程序中,定义一个内部 table,其中的行类型类似于数据库视图。
- 使用
UPDATE dbtab FROM TABLE itab
更新数据库视图。键字段中定义的行将被 selected,非键列将被更新。 - 我在这里不讨论如何编写构造函数表达式 (
... @( VALUE #( ... ) )
),因为您认为它可以解决您的问题的假设是错误的。
ABAP 中有一些方法可以更新几列或几行,但不能同时更新:
- 2) 将给定列设置为固定值 - 在所有更新的行中,这些列将具有相同的值:
UPDATE dbtab SET col1 = value1 col2 = value2 ... \[WHERE ...\]
。您可以在循环内重复UPDATE ... SET ...
以模仿批量更新。它将比通过数据库视图更新(案例 2)慢,我不确定它是否比案例 3 快或慢(可能取决于列数)。 - 3) 如果您可以确定
itab
在您不感兴趣的所有其他列中包含正确的值,您仍然可以考虑使用UPDATE dbtab FROM TABLE itab
。您可以考虑防止并发更新(由其他程序 运行 并行或最终由另一个用户使用同一程序 运行)使用锁,以避免在SELECT
之间进行一些更新以初始化内部 table 和UPDATE
.
注意:我不明白你为什么说 LOOP 是 Code Inspector 和性能的问题。构造函数表达式(如您所说的 "new syntax" )用于避免中间变量,对于 better readability and to focus on final goal.
以下语法有效:
TYPES: ttcurr TYPE TABLE OF tcurr WITH EMPTY KEY.
SELECT ukurs, tcurr, gdatu
FROM tcurr
INTO TABLE @DATA(ltcurr)
UP TO 100 ROWS.
DATA(it_modified) = VALUE ttcurr( FOR ls_tcurr IN ltcurr ( ukurs = ls_tcurr-ukurs / 1000 tcurr = ls_tcurr-tcurr gdatu = ls_tcurr-gdatu ) ).
UPDATE tcurr FROM TABLE @(
VALUE ttcurr(
FOR ls_curr IN it_modified WHERE ( tcurr NE 'EUR' AND gdatu > '79989898' )
( ukurs = ls_curr-ukurs ) ) ).
BASE
在您的代码段中使用错误,当您用 table 表达式填充一些 itab 并希望保留其以前的内容时使用它,它只接受 itab 操作数。在我们的例子中,更新 dbtab 时可以省略它。
您不能在此语句中使用内联类型,也不能在 WHERE
.
ls_doc61
进行比较
尝试将您的代码段更改为类似的内容:
TYPES: ttdoc TYPE TABLE OF ZBWEVATDOC61 WITH EMPTY KEY.
UPDATE ZBWEVATDOC61 FROM TABLE @(
VALUE ttdoc(
FOR ls_doc61 IN it_doc61 WHERE ( cuv = 'smth' AND folio = 'smth' AND folio_interno = 'smth' )
( estado = ls_doc61-estado ) ) ).