Всем понятно, что Native SQL лучше, а Open SQL переносимее.
В зависимости от постановки задачи можно использовать и то, и другое. Когда большинство инсталляций будет над MaxDB, можно будет смело использовать Native.
Добавил возможность делать join.
Code:
REPORT zqk00523 .
PARAMETERS:
v_sql(1024) DEFAULT 'select mara~matnr ernam MAKTX from mara inner join makt on mara~matnr = makt~matnr and spras = ''R'' up to 10 rows.'
, p_langu TYPE sy-langu DEFAULT 'RU'
, p_list RADIOBUTTON GROUP aa
, p_alv RADIOBUTTON GROUP aa DEFAULT 'X'
.
DATA: r_dat TYPE REF TO data
, r_dsc TYPE REF TO cl_abap_typedescr
, r_elm TYPE REF TO cl_abap_elemdescr
, t_dsc TYPE string
, s_elm TYPE dfies
, pos TYPE i VALUE 1
, r_cnt TYPE REF TO cl_gui_custom_container
, r_alv TYPE REF TO cl_gui_alv_grid
, code TYPE TABLE OF char1024 WITH HEADER LINE
, gt_lvc_fieldcat TYPE lvc_t_fcat
, l_sql(1024)
.
FIELD-SYMBOLS: <r> TYPE ANY
, <f> TYPE ANY
, <g> TYPE ANY
, <out> TYPE ANY TABLE.
TOP-OF-PAGE.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <r> TO <g>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
r_dsc = cl_abap_typedescr=>describe_by_data( <g> ) .
r_elm ?= r_dsc.
s_elm = r_elm->get_ddic_field( p_langu ).
WRITE: AT pos s_elm-reptext.
pos = pos + s_elm-outputlen + 1.
ENDDO.
ULINE.
START-OF-SELECTION.
PERFORM start_of_selection.
*&--------------------------------------------------------------------*
*& Form start_of_selection
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
FORM start_of_selection.
DATA: s1(1024), s2(1024), s3(1024)
, prog(20)
, msg(1024), lin TYPE i, wrd(100), off TYPE i
, p_tab TYPE dd02l-tabname
, wa_tab TYPE dd02l-tabname
, j_tabs TYPE TABLE OF char64
, t_fields TYPE TABLE OF dd03l-fieldname
, i TYPE i
, select_all
, tab_name TYPE dd02l-tabname
, field_name TYPE dd03l-fieldname
, as_name TYPE dd03l-fieldname
, wa_dd03l TYPE dd03l
, ls_lvc_fieldcat TYPE lvc_s_fcat
.
DATA: BEGIN OF t_fields_as_name OCCURS 10
, fieldname TYPE dd03l-fieldname
, END OF t_fields_as_name
.
FIELD-SYMBOLS: <field> TYPE dd03p-fieldname
, <table> LIKE LINE OF j_tabs
, <ls_lvc_outtab> TYPE ANY
" <l_field> TYPE ANY
.
CONDENSE v_sql.
TRANSLATE v_sql TO UPPER CASE.
SPLIT v_sql AT ' FROM ' INTO s1 s2.
SPLIT s2 AT space INTO p_tab s2.
APPEND p_tab TO j_tabs.
REFRESH t_fields[].
SPLIT s2 AT ' JOIN ' INTO TABLE t_fields.
LOOP AT t_fields ASSIGNING <field>.
IF sy-tabix = 1. CONTINUE. ENDIF.
SPLIT <field> AT space INTO wa_tab s3.
IF sy-subrc = 0.
APPEND wa_tab TO j_tabs.
ENDIF.
ENDLOOP.
REFRESH t_fields[].
SPLIT s1 AT space INTO TABLE t_fields.
DELETE t_fields WHERE table_line = ''.
DELETE t_fields INDEX 1.
DESCRIBE TABLE t_fields LINES i.
READ TABLE t_fields INDEX 1 ASSIGNING <field>.
IF i = 1 AND <field> = '*'.
select_all = 'X'.
ELSE.
select_all = ''.
ENDIF.
REFRESH code.
APPEND 'PROGRAM SUBPOOL.' TO code.
APPEND 'FORM get_data using s1 changing tab1.' TO code.
IF select_all = ''.
CONCATENATE s1 'INTO TABLE T_OUT FROM' p_tab s2
INTO l_sql SEPARATED BY ' '.
APPEND 'types: begin of output_table' TO code.
DATA: fl1.
CLEAR wa_dd03l. CLEAR as_name. CLEAR fl1.
LOOP AT t_fields ASSIGNING <field>.
IF fl1 = 'X'.
IF <field> = 'AS'. as_name = '-'. CONTINUE. ENDIF.
IF as_name = '-'. as_name = <field>. CONTINUE. ENDIF.
PERFORM process_field USING as_name wa_dd03l.
CLEAR wa_dd03l. CLEAR as_name. fl1 = ''.
ENDIF.
fl1 = 'X'.
SEARCH <field> FOR '~'.
IF sy-subrc = 0.
SPLIT <field> AT '~' INTO tab_name field_name.
SELECT SINGLE * INTO wa_dd03l FROM dd03l
WHERE tabname = tab_name
AND fieldname = field_name.
ELSE.
LOOP AT j_tabs ASSIGNING <table>.
SELECT SINGLE * INTO wa_dd03l FROM dd03l
WHERE tabname = <table>
AND fieldname = <field>.
CHECK sy-subrc = 0.
ENDLOOP.
ENDIF.
ENDLOOP.
PERFORM process_field USING as_name wa_dd03l.
APPEND ' , end of output_table.' TO code.
APPEND 'data: T_OUT TYPE table of output_table.' TO code.
APPEND 'data: r_dat TYPE REF TO data.' TO code.
APPEND 'FIELD-SYMBOLS : <out> TYPE ANY TABLE.' TO code.
APPEND 'CREATE DATA r_dat TYPE STANDARD TABLE OF output_table.' TO code.
APPEND 'ASSIGN r_dat->* TO <out>.' TO code.
APPEND l_sql TO code.
APPEND '<out> = T_OUT.' TO code.
APPEND 'tab1 = <out>.' TO code.
APPEND 'ENDFORM.' TO code.
GENERATE SUBROUTINE POOL code
NAME prog MESSAGE msg LINE lin WORD wrd OFFSET off.
IF sy-subrc <> 0.
MESSAGE i666(01) WITH msg.
EXIT.
ELSE.
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = gt_lvc_fieldcat
IMPORTING
ep_table = r_dat.
ASSIGN r_dat->* TO <out>.
PERFORM get_data IN PROGRAM (prog)
USING p_tab CHANGING <out>.
ENDIF.
CASE 'X'.
WHEN p_list.
ASSIGN LOCAL COPY OF INITIAL LINE OF <out>
TO <ls_lvc_outtab>.
LOOP AT <out> ASSIGNING <ls_lvc_outtab>.
NEW-LINE.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <ls_lvc_outtab> TO <f>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
WRITE: <f>.
ENDDO.
ENDLOOP.
WHEN p_alv.
CREATE OBJECT r_cnt EXPORTING container_name = 'OUT01'.
CREATE OBJECT r_alv EXPORTING i_parent = r_cnt.
CALL METHOD r_alv->set_table_for_first_display
* EXPORTING
* i_structure_name = ''
CHANGING
it_fieldcatalog = gt_lvc_fieldcat
it_outtab = <out>
.
CALL SCREEN 100.
ENDCASE.
***********************************
ELSE. " select_all = 'X'.
CONCATENATE s1 'INTO TABLE <OUT> FROM' p_tab s2
INTO v_sql SEPARATED BY ' '.
APPEND 'data: r_dat TYPE REF TO data.' TO code.
APPEND 'FIELD-SYMBOLS : <out> TYPE ANY TABLE.' TO code.
APPEND 'CREATE DATA r_dat TYPE STANDARD TABLE OF (s1).' TO code.
APPEND 'ASSIGN r_dat->* TO <out>.' TO code.
APPEND v_sql TO code.
APPEND 'tab1 = <OUT>.' TO code.
APPEND 'ENDFORM.' TO code.
GENERATE SUBROUTINE POOL code
NAME prog MESSAGE msg LINE lin WORD wrd OFFSET off.
IF sy-subrc <> 0.
MESSAGE i666(01) WITH msg.
EXIT.
ELSE.
CREATE DATA r_dat TYPE STANDARD TABLE OF (p_tab).
ASSIGN r_dat->* TO <out>.
PERFORM get_data IN PROGRAM (prog)
USING p_tab CHANGING <out>.
ENDIF.
CASE 'X'.
WHEN p_list.
LOOP AT <out> ASSIGNING <r>.
NEW-LINE.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <r> TO <f>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
WRITE: <f>.
ENDDO.
ENDLOOP.
WHEN p_alv.
CREATE OBJECT r_cnt EXPORTING container_name = 'OUT01'.
CREATE OBJECT r_alv EXPORTING i_parent = r_cnt.
CALL METHOD r_alv->set_table_for_first_display
EXPORTING
i_structure_name = p_tab
CHANGING
it_outtab = <out>.
CALL SCREEN 100.
ENDCASE.
ENDIF.
ENDFORM. "start_of_selection
*&--------------------------------------------------------------------*
*& Form process_field
*&--------------------------------------------------------------------*
* text
*---------------------------------------------------------------------*
* -->AS_NAME text
* -->WA_DD03L text
*---------------------------------------------------------------------*
FORM process_field USING as_name wa_dd03l TYPE dd03l.
DATA: line(1024)
, ls_lvc_fieldcat TYPE lvc_s_fcat
.
IF as_name IS INITIAL.
as_name = wa_dd03l-fieldname.
ENDIF.
CONCATENATE wa_dd03l-tabname '-' wa_dd03l-fieldname
INTO line.
CONCATENATE ' ,' as_name 'type' line
INTO line SEPARATED BY ' '.
APPEND line TO code.
MOVE-CORRESPONDING wa_dd03l TO ls_lvc_fieldcat.
APPEND ls_lvc_fieldcat TO gt_lvc_fieldcat.
ENDFORM. "process_field