сделал отдельный инклюд для боле/мение удобной работы с Natve SQL.
позволяет работать с range почти также как OPEN SQL
Code:
*&---------------------------------------------------------------------*
*& Include YDK_NATIVE_SQL_INC
*&---------------------------------------------------------------------*
DATA: dbs TYPE dbcon-con_name.
DATA: ctopen TYPE i.
DATA: sql_str TYPE string.
*&---------------------------------------------------------------------*
*& Form open_connection
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM open_connection USING adbs.
DATA dbtype TYPE dbcon_dbms.
IF NOT dbs IS INITIAL.
IF dbs = adbs.
ADD 1 TO ctopen.
EXIT.
ELSE.
MESSAGE e009(zdk1) WITH dbs adbs.
ENDIF.
ENDIF.
dbs = adbs.
ctopen = 1.
SELECT SINGLE dbms
FROM dbcon
INTO dbtype
WHERE con_name = dbs.
IF sy-subrc <> 0.
RAISE dbco_error.
ENDIF.
EXEC SQL.
connect to :dbs
ENDEXEC.
IF sy-subrc <> 0.
RAISE connect_error.
ENDIF.
ENDFORM. "open_connection
*&---------------------------------------------------------------------*
*& Form close_connection
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM close_connection.
SUBTRACT 1 FROM ctopen.
CHECK ctopen IS INITIAL.
EXEC SQL.
disconnect :dbs
ENDEXEC.
CLEAR dbs.
ENDFORM. "close_connection
*&---------------------------------------------------------------------*
*& Form convert_val2sql
*&---------------------------------------------------------------------*
* преобразует значение переменной в строку в формате MS SQL сервер
*----------------------------------------------------------------------*
* -->TYP тип переменной (не обязательно)
* -->VAR переменная
* -->STR возвращаемая строка
*----------------------------------------------------------------------*
FORM convert_val2sql USING typ var str.
DATA: vtyp(2) TYPE c.
DATA: sd(10) TYPE c.
IF typ = '?'.
DESCRIBE FIELD var TYPE vtyp.
ELSE.
vtyp = typ.
ENDIF.
CASE vtyp(1).
WHEN 'C'.
str = var.
WHEN 'I' OR 'F' OR 'P'.
WRITE var TO str LEFT-JUSTIFIED NO-ZERO NO-GROUPING.
WHEN 'N'.
WRITE var TO str LEFT-JUSTIFIED NO-GROUPING.
WHEN 'D'.
sd(4) = var(4).
sd+4(1) = '-'.
sd+5(2) = var+4(2).
sd+7(1) = '-'.
sd+8(2) = var+6(2).
CASE vtyp+1.
WHEN ' '.
str = sd.
WHEN 'L'.
CONCATENATE sd '#00:00:00.000' INTO str.
WHEN 'H'.
CONCATENATE sd '#23:59:59.999' INTO str.
WHEN 'B'.
CONCATENATE 'BETWEEN "' sd '#00:00:00.000" AND "' sd '#23:59:59.999"'
INTO str.
ENDCASE.
WHEN OTHERS.
WRITE var TO str LEFT-JUSTIFIED.
ENDCASE.
ENDFORM. "convert_val2sql
*&---------------------------------------------------------------------*
*& Form add_sql
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->VAR text
*----------------------------------------------------------------------*
FORM add_sql USING var.
DATA: str(300) TYPE c.
DATA: typ TYPE c.
FIELD-SYMBOLS <tab> TYPE STANDARD TABLE.
DESCRIBE FIELD var TYPE typ.
IF typ = 'h'. " Внутрення таблица
ASSIGN var TO <tab>.
PERFORM add_range2sql TABLES <tab>.
ELSE.
PERFORM convert_val2sql USING typ var str.
IF sql_str IS INITIAL.
sql_str = str.
ELSE.
CONCATENATE sql_str str INTO sql_str
SEPARATED BY space.
ENDIF.
ENDIF.
ENDFORM. "add_sql
*&---------------------------------------------------------------------*
*& Form add_range2sql
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->TAB text
*----------------------------------------------------------------------*
FORM add_range2sql TABLES tab.
DATA: typ(2) TYPE c.
DATA: op(2) TYPE c.
DATA: fstr(100) TYPE c.
DATA: rstr TYPE string.
DATA: len TYPE i.
DATA: ch TYPE c.
DATA: word_num TYPE i.
DATA: str(100) TYPE c.
DATA: lstr(100) TYPE c.
DATA: hstr(100) TYPE c.
FIELD-SYMBOLS: <sign>, <option>, <low>, <high>.
ASSIGN COMPONENT 'SIGN' OF STRUCTURE tab TO <sign>.
CHECK sy-subrc = 0.
ASSIGN COMPONENT 'OPTION' OF STRUCTURE tab TO <option>.
CHECK sy-subrc = 0.
ASSIGN COMPONENT 'LOW' OF STRUCTURE tab TO <low>.
CHECK sy-subrc = 0.
ASSIGN COMPONENT 'HIGH' OF STRUCTURE tab TO <high>.
CHECK sy-subrc = 0.
DESCRIBE FIELD <low> TYPE typ.
* откручиваем назад для выбота имени переменной для range
len = STRLEN( sql_str ).
DO.
SUBTRACT 1 FROM len.
ch = sql_str+len(1).
IF ch CA ' ('.
ADD 1 TO word_num.
CASE word_num.
WHEN 1.
TRANSLATE fstr TO UPPER CASE.
IF fstr <> 'IN'.
MESSAGE x023(zdk1).
ENDIF.
CLEAR fstr.
WHEN 2.
EXIT.
ENDCASE.
ELSE.
CONCATENATE ch fstr INTO fstr.
ENDIF.
ENDDO.
ADD 1 TO len.
* строим range
LOOP AT tab.
CASE <option>.
WHEN 'EQ'. op = '='.
WHEN 'NE'. op = '<>'.
WHEN 'LT'. op = '<'.
WHEN 'GT'. op = '>'.
WHEN 'LE'. op = '<='.
WHEN 'GE'. op = '>='.
WHEN 'BT'.
typ+1(1) = 'L'.
PERFORM convert_val2sql USING typ <low> lstr.
typ+1(1) = 'H'.
PERFORM convert_val2sql USING typ <low> hstr.
CONCATENATE 'BETWEEN "' lstr '" AND "' hstr '"' INTO str.
WHEN OTHERS.
CONTINUE.
ENDCASE.
IF <option> <> 'BT'.
IF typ(1) = 'D'.
typ+1(1) = 'B'.
PERFORM convert_val2sql USING typ <low> str.
ELSE.
typ+1(1) = 'L'.
PERFORM convert_val2sql USING typ <low> str.
CONCATENATE op '#' str INTO str.
ENDIF.
ENDIF.
CONCATENATE rstr 'OR' fstr str INTO rstr
SEPARATED BY space.
ENDLOOP.
* добавляем range
CONCATENATE sql_str(len) '#(' rstr+4 ')' INTO sql_str.
ENDFORM. "add_range2sql
*&---------------------------------------------------------------------*
*& Form open_sql
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM open_sql.
TRANSLATE sql_str USING '# "'''.
CONDENSE sql_str.
EXEC SQL.
OPEN dbcur FOR
SELECT * FROM $PROC$sys.sp_sqlexec
WHERE (:sql_str)
ENDEXEC.
CLEAR sql_str.
ENDFORM. "open_sql
DEFINE fetch_tab.
refresh &1.
do.
exec sql.
fetch next dbcur into :&1
endexec.
if sy-subrc <> 0. exit. endif.
append &1.
enddo.
exec sql.
close dbcur
endexec.
END-OF-DEFINITION.
вот пример запроса
Code:
SELECT-OPTIONS: sdateb FOR xdateb.
...................
PERFORM add_sql USING:
'SELECT Contractor, Count(*) as Count',
'FROM dbo.SAP_v_Races',
'WHERE ZKVBL IS NULL',
'AND DATEB IN', sdateb[],
'GROUP BY Contractor, To_Lease'.
PERFORM open_sql.
fetch_tab itxcg.