处理连接 table 键的通用方法
Generic way of handling concatenated table key
如果我有一个 tabkey
值,例如 DATA(lv_tabkey) = '1000041508773180000013000'.
,它是一个条目的所有 table 键的串联值,并且我知道对应的 table:
如何在不手动拆分 tabkey
的情况下获得 table 条目,因此必须写下每个关键字段的顺序和长度?
完整示例:
" The first 3 chars always belong to the 'mandt' field
" which can't be filtered in the SELECT, therefore
" I ignore it and start with key2
DATA(lv_tabkey) = '1000041508773180000013000'.
"ToDo - how to make this generic? - START
DATA(lv_key2) = lv_tabkey+3(12).
DATA(lv_key3) = lv_tabkey+15(3).
DATA(lv_key4) = lv_tabkey+18(4).
DATA(lv_key5) = lv_tabkey+22(3).
DATA(lv_where) = 'key2 = ' && lv_key2 &&
' AND key3 = ' && lv_key3 &&
' AND key4 = ' && lv_key4 &&
' AND key5 = ' && lv_key5.
"ToDo - how to make this generic? - END
SELECT *
FROM table_x
INTO TABLE DATA(lt_results)
WHERE (lv_where).
我想我必须以某种方式遍历 table 字段,找出键及其长度 - 但我不知道该怎么做。
您的用例让我想起了我如何处理更改文档密钥。(CDHDR/CDPOS)。
希望能帮助到你!
DATA:
lv_tabkey TYPE char50,
ls_table TYPE table_x.
FIELD-SYMBOLS:
<ls_src_x> TYPE x,
<ls_tgt_x> TYPE x.
"Add Client info the Table key if your table is Client dependent.
CONCATENATE sy-mandt lv_tabkey INTO lv_tabkey.
ASSIGN lv_tab_key TO <ls_src_x> CASTING.
ASSIGN ls_table TO <ls_tgt_x> CASTING.
<ls_tgt_x> = <ls_src_x>.
"Now ls_table has the key info filled including MANDT if you have the MANDT in table key.
SELECT *
FROM table_x
INTO TABLE DATA(lt_results)
WHERE key2 = ls_table-key2 AND key3 = ls_table-key3
AND key4 = ls_table-key4 AND key5 = ls_table_key5.
您要查询的语句是:
ASSIGN tabkey TO < structure> CASTING TYPE HANDLE r_type_struct.
了解(table 键)结构的类型句柄后,您可以用通用方式为其填充值,并使用该结构查询 table。方法如下:
DATA: handle TYPE REF TO data,
lref_struct TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS: <key_fld> TYPE abap_componentdescr.
SELECT * UP TO 5000 ROWS
FROM cdpos
INTO TABLE @DATA(t_cdpos)
WHERE tabname NOT LIKE '/%'.
LOOP AT t_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>).
lref_struct ?= cl_abap_structdescr=>describe_by_name( <fs_cdpos>-tabname ).
* get key fields
DATA(key_fields) = VALUE ddfields( FOR line IN lref_struct->get_ddic_field_list( ) WHERE ( keyflag NE space ) ( line ) ).
* filling key field components
DATA(key_table) = VALUE abap_component_tab( FOR ls_key IN key_fields
( name = ls_key-fieldname
type = CAST #( cl_abap_datadescr=>describe_by_name( ls_key-domname ) )
)
).
* create key fields type handle
TRY.
DATA(r_type_struct) = cl_abap_structdescr=>create( key_table ).
CATCH cx_sy_struct_creation .
ENDTRY.
* create key type
CHECK r_type_struct IS NOT INITIAL.
CREATE DATA handle TYPE HANDLE r_type_struct.
ASSIGN handle->* TO FIELD-SYMBOL(<structure>).
* assigning final key structure
ASSIGN <fs_cdpos>-tabkey TO <structure> CASTING TYPE HANDLE r_type_struct.
* filling values
LOOP AT key_table ASSIGNING <key_fld>.
ASSIGN COMPONENT <key_fld>-name OF STRUCTURE <structure> TO FIELD-SYMBOL(<val>).
CHECK sy-subrc = 0.
<key_fld>-suffix = <val>.
ENDLOOP.
DATA(where_cond) = REDUCE string( INIT where = ` ` FOR <field> IN key_table WHERE ( name <> 'MANDT' ) NEXT where = where && <field>-name && ` = '` && <field>-suffix && `' AND ` ).
where_cond = substring( val = where_cond off = 0 len = strlen( where_cond ) - 4 ).
IF <fs_cdpos>-tabname = 'BNKA'.
SELECT *
INTO TABLE @DATA(lt_bnka)
FROM bnka
WHERE (where_cond).
ENDIF.
ENDLOOP.
这里我在 table CDPOS
上构建了示例,其中包含 table 名称和字段 tabkey
中额外连接的键值,换句话说正是您正在尝试的使用。
在一个循环中,它检测 table 类型,构建密钥并以通用方式进行 SQL 查询。这里为了简单起见,我使用了 table BNKA
,但是 SQL SELECT 也可以通过字段符号进行泛化。我还通过在 SUFFIX
字段中将值填充到包含结构组件的同一选项卡中做了一个技巧。
P.S。在将 where 条件传递给查询之前,请进行适当的数据类型验证以避免 SAPSQL_DATA_LOSS 等错误,因为使用新语法会进行严格检查。
如果我有一个 tabkey
值,例如 DATA(lv_tabkey) = '1000041508773180000013000'.
,它是一个条目的所有 table 键的串联值,并且我知道对应的 table:
如何在不手动拆分 tabkey
的情况下获得 table 条目,因此必须写下每个关键字段的顺序和长度?
完整示例:
" The first 3 chars always belong to the 'mandt' field
" which can't be filtered in the SELECT, therefore
" I ignore it and start with key2
DATA(lv_tabkey) = '1000041508773180000013000'.
"ToDo - how to make this generic? - START
DATA(lv_key2) = lv_tabkey+3(12).
DATA(lv_key3) = lv_tabkey+15(3).
DATA(lv_key4) = lv_tabkey+18(4).
DATA(lv_key5) = lv_tabkey+22(3).
DATA(lv_where) = 'key2 = ' && lv_key2 &&
' AND key3 = ' && lv_key3 &&
' AND key4 = ' && lv_key4 &&
' AND key5 = ' && lv_key5.
"ToDo - how to make this generic? - END
SELECT *
FROM table_x
INTO TABLE DATA(lt_results)
WHERE (lv_where).
我想我必须以某种方式遍历 table 字段,找出键及其长度 - 但我不知道该怎么做。
您的用例让我想起了我如何处理更改文档密钥。(CDHDR/CDPOS)。 希望能帮助到你!
DATA:
lv_tabkey TYPE char50,
ls_table TYPE table_x.
FIELD-SYMBOLS:
<ls_src_x> TYPE x,
<ls_tgt_x> TYPE x.
"Add Client info the Table key if your table is Client dependent.
CONCATENATE sy-mandt lv_tabkey INTO lv_tabkey.
ASSIGN lv_tab_key TO <ls_src_x> CASTING.
ASSIGN ls_table TO <ls_tgt_x> CASTING.
<ls_tgt_x> = <ls_src_x>.
"Now ls_table has the key info filled including MANDT if you have the MANDT in table key.
SELECT *
FROM table_x
INTO TABLE DATA(lt_results)
WHERE key2 = ls_table-key2 AND key3 = ls_table-key3
AND key4 = ls_table-key4 AND key5 = ls_table_key5.
您要查询的语句是:
ASSIGN tabkey TO < structure> CASTING TYPE HANDLE r_type_struct.
了解(table 键)结构的类型句柄后,您可以用通用方式为其填充值,并使用该结构查询 table。方法如下:
DATA: handle TYPE REF TO data,
lref_struct TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS: <key_fld> TYPE abap_componentdescr.
SELECT * UP TO 5000 ROWS
FROM cdpos
INTO TABLE @DATA(t_cdpos)
WHERE tabname NOT LIKE '/%'.
LOOP AT t_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>).
lref_struct ?= cl_abap_structdescr=>describe_by_name( <fs_cdpos>-tabname ).
* get key fields
DATA(key_fields) = VALUE ddfields( FOR line IN lref_struct->get_ddic_field_list( ) WHERE ( keyflag NE space ) ( line ) ).
* filling key field components
DATA(key_table) = VALUE abap_component_tab( FOR ls_key IN key_fields
( name = ls_key-fieldname
type = CAST #( cl_abap_datadescr=>describe_by_name( ls_key-domname ) )
)
).
* create key fields type handle
TRY.
DATA(r_type_struct) = cl_abap_structdescr=>create( key_table ).
CATCH cx_sy_struct_creation .
ENDTRY.
* create key type
CHECK r_type_struct IS NOT INITIAL.
CREATE DATA handle TYPE HANDLE r_type_struct.
ASSIGN handle->* TO FIELD-SYMBOL(<structure>).
* assigning final key structure
ASSIGN <fs_cdpos>-tabkey TO <structure> CASTING TYPE HANDLE r_type_struct.
* filling values
LOOP AT key_table ASSIGNING <key_fld>.
ASSIGN COMPONENT <key_fld>-name OF STRUCTURE <structure> TO FIELD-SYMBOL(<val>).
CHECK sy-subrc = 0.
<key_fld>-suffix = <val>.
ENDLOOP.
DATA(where_cond) = REDUCE string( INIT where = ` ` FOR <field> IN key_table WHERE ( name <> 'MANDT' ) NEXT where = where && <field>-name && ` = '` && <field>-suffix && `' AND ` ).
where_cond = substring( val = where_cond off = 0 len = strlen( where_cond ) - 4 ).
IF <fs_cdpos>-tabname = 'BNKA'.
SELECT *
INTO TABLE @DATA(lt_bnka)
FROM bnka
WHERE (where_cond).
ENDIF.
ENDLOOP.
这里我在 table CDPOS
上构建了示例,其中包含 table 名称和字段 tabkey
中额外连接的键值,换句话说正是您正在尝试的使用。
在一个循环中,它检测 table 类型,构建密钥并以通用方式进行 SQL 查询。这里为了简单起见,我使用了 table BNKA
,但是 SQL SELECT 也可以通过字段符号进行泛化。我还通过在 SUFFIX
字段中将值填充到包含结构组件的同一选项卡中做了一个技巧。
P.S。在将 where 条件传递给查询之前,请进行适当的数据类型验证以避免 SAPSQL_DATA_LOSS 等错误,因为使用新语法会进行严格检查。