Текущее время: Пн, авг 04 2025, 21:36

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
 Заголовок сообщения: Динамический Native SQL для MS SQL server-a
СообщениеДобавлено: Пн, янв 12 2009, 08:32 
Менеджер
Менеджер
Аватара пользователя

Зарегистрирован:
Чт, мар 09 2006, 10:12
Сообщения: 565
Откуда: Волгодонск
Пол: Мужской
Собственно решение (может кому пригодится):
Code:
  sql_str = 'select ...'. " собственно строка SQL запроса для MS SQL

  EXEC SQL.
    OPEN dbcur FOR
    SELECT * FROM $PROC$sys.sp_sqlexec
     WHERE (:sql_str)
  ENDEXEC.

  do.
    exec sql.
      fetch next dbcur into :itab
    endexec.

    if sy-subrc <> 0. exit. endif.

    append itab.
  enddo.


смысл следующий: вызывается стандартная хранимая процедура sys.sp_sqlexec в неё передаётся строка с запросом
процедура выполняет запрос и возвращает его результат

_________________
Изображение Попытка не пытка


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Динамический Native SQL для MS SQL server-a
СообщениеДобавлено: Пн, янв 12 2009, 08:35 
Менеджер
Менеджер
Аватара пользователя

Зарегистрирован:
Чт, мар 09 2006, 10:12
Сообщения: 565
Откуда: Волгодонск
Пол: Мужской
сделал отдельный инклюд для боле/мение удобной работы с 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.

_________________
Изображение Попытка не пытка


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB