Текущее время: Пн, июл 21 2025, 00:50

Часовой пояс: 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 часа


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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