Sapforum.Biz

Инструменты => ABAP - Инструментальные средства => Тема розпочата: Sed0Y від Травень 19, 2011, 06:26:30 ПП

Назва: RFC через ODBC используя C++
Відправлено: Sed0Y від Травень 19, 2011, 06:26:30 ПП
Не знаю точно в какой раздет размещать, поместил сюда - так что сильно не пинайте.


Есть такие кто передает - дергает данные через ODBC?
меня волнует такой вопрос

как с С++ вернуть в САП таблицу с данными которые получаю запросом к базе???
Получить данные могу

...
RETCODE retcode;// Return code
SQLCHAR     one[10],
                   two[10];
...
SQLCHAR *sqlStr = (SQLCHAR *)"{SELECT one two FROM tabl where 1<>2}";
....
        retcode = SQLExecDirect(hSqlStmt, sqlStr, SQL_NTS);
        if (retcode != SQL_SUCCESS )
{
printf("Error SQL Execute Direct\n");
}

        retcode = SQLBindCol(hSqlStmt, 1, SQL_CHAR, (SQLPOINTER) one, sizeof(one), &rlength);
        if (retcode != SQL_SUCCESS )
{
printf("Error binding one\n");
}
        retcode = SQLBindCol(hSqlStmt, 2, SQL_CHAR, (SQLPOINTER) two, sizeof(two), &rlength);
        if (retcode != SQL_SUCCESS )
{
printf("Error binding two\n");
}

i = 0;
while ((retcode = SQLFetch(hSqlStmt)) == SQL_SUCCESS)
{
printf("\n %s %s", one, two); // тут вывожу свои параметры
}


Одно заначение вернуть не проблема к примеру:

memsetR (&parameters[0], 0, sizeofR(parameters));
parameters[0].name = cU("MESSAGE");
parameters[0].nlen = strlenU ((rfc_char_t*) parameters[0].name);
parameters[0].addr = &mess;
parameters[0].leng = 0;
parameters[0].type = RFCTYPE_STRING;


parameters[1].name = NULL;

tables[0].name = NULL; /* no tables */

rfc_rc = RfcSendData (rfc_handle,
  parameters,
  tables
);
return rfc_rc;
}


А вот как их всунуть в таблицу и вернуть, не заню...
Назва: Re: RFC через ODBC используя C++
Відправлено: №1 від Травень 20, 2011, 11:11:08 ДП
Цитата: Sed0Y від Травень 19, 2011, 06:26:30 ПП
как с С++ вернуть в САП таблицу с данными которые получаю запросом к базе???
Очень сильно не советую кидать данные в базу минуя сервер приложений SAP. Вас базисники просто убьют!!!
Назва: Re: RFC через ODBC используя C++
Відправлено: NachDenken від Травень 20, 2011, 01:41:45 ПП
лучше использовать BAPI, они как раз для этого придуманы.
Назва: Re: RFC через ODBC используя C++
Відправлено: NachDenken від Травень 20, 2011, 01:58:35 ПП
Цитата: №1 від Травень 20, 2011, 11:11:08 ДП
Очень сильно не советую кидать данные в базу минуя сервер приложений SAP. Вас базисники просто убьют!!!
остается вопрос как базисники ему дали права на оракловскую базу :)
Назва: Re: RFC через ODBC используя C++
Відправлено: Dmitriy від Травень 20, 2011, 03:37:07 ПП
Цитата: NachDenken від Травень 20, 2011, 01:58:35 ПП
остается вопрос как базисники ему дали права на оракловскую базу :)
Православные базисники исчо не то иногда учудяють-с! :D
Назва: Re: RFC через ODBC используя C++
Відправлено: Sed0Y від Травень 23, 2011, 05:15:01 ПП
Спасибо всем за внимание. я разобрался как это сделать. Если кому-то будет нужно, напишите я расскажу, т.к. много писать.

А по поводу "Очень сильно не советую кидать данные в базу минуя сервер приложений SAP. Вас базисники просто убьют!!!"
я может не полностью описал потребность этого...

коротко - Я с САПа передаю кое какие данные (другой фирме, к другой БД..., где нет доступа к САП а может и есть, но если так сделано значит нужно...), там они обрабатываются и таблицой мне возвращают эти обработанные данные, потом я эти данные обрабатываю (уже на стороне САПа) и заношу в "Z" таблицы(поля) в САПе...
Назва: Re: RFC через ODBC используя C++
Відправлено: Uukrul від Травень 23, 2011, 08:30:39 ПП
Цитата: Sed0Y від Травень 23, 2011, 05:15:01 ПП
коротко - Я с САПа передаю кое какие данные (другой фирме, к другой БД..., где нет доступа к САП а может и есть, но если так сделано значит нужно...), там они обрабатываются и таблицой мне возвращают эти обработанные данные, потом я эти данные обрабатываю (уже на стороне САПа) и заношу в "Z" таблицы(поля) в САПе...
Так это что ремоутконекшен надо было просто к другой базе сделать и все? Опять же много писать... это не причина не написать.
Назва: Re: RFC через ODBC используя C++
Відправлено: Sed0Y від Травень 24, 2011, 02:23:09 ДП
я почти так и написал в теме... Только используя С++
Только для этого уже существует написан на С++ проект для работы...
Я подумал, что если кто с таким уже работал, то он бы узнал...

Цитата: Uukrul від Травень 23, 2011, 08:30:39 ПП
Опять же много писать... это не причина не написать.

Напишу конечно... Когда буду на работе...
Назва: Re: RFC через ODBC используя C++
Відправлено: Nexus від Травень 24, 2011, 10:10:39 ДП
А пользоваться SAP RFC SDK(будет поддержка балансировки и другие плюшки "официального подключения") не пробовали, единственное что нужно будет написать две RFC функции на ABAP одна которая выберет данные, другая положит.
(if you are SAP customer you can find it on http://service.sap.com/swdc under Patches for My Company's Application Components - SAP RFC SDK)
Назва: Re: RFC через ODBC используя C++
Відправлено: Sed0Y від Червень 03, 2011, 04:01:05 ПП
как и обещал
В САП, создаем структуру таблицы которую мы будем получать заполненную в С++
у меня было всего 2 поля(целочисленных):
назовем ее ZSRFC
поля:
RFCAID   RFCINT4
RFCBID   RFCINT4


DATA:
      gv_mess(256),
      ls_frc   TYPE ZSRFC            " структура которую мы пепредаем по РФЦ в С++

  CALL FUNCTION 'GETDATA' DESTINATION 'RFC_C'
    EXPORTING
      IMPORTSTRUCT          = ls_frc " передаем туда нашу структуру
    IMPORTING
      RET                   = RESULT " тут я себе получаю результат
      MESS                  = MESS  " ну и если есть ошибка то описание ее
    TABLES
      RFCTABLE              = G_IE " собственно данные
    EXCEPTIONS
      COMMUNICATION_FAILURE = 1  MESSAGE gv_mess
      SYSTEM_FAILURE        = 2  MESSAGE gv_mess
      .


в С++ мы описываем структуру и поля покторые получим и которые будем заполнять:

static RFC_TYPEHANDLE handleOfRfcIE;

typedef struct RFCIE
{
        SAP_INT rfcaid;
#define RFCIE_RFCAID_LN      4
#define RFCIE_RFCAID_TYP     RFCTYPE_INT

        SAP_INT rfcbid;
#define RFCIE_RFCBID_LN      4
#define RFCIE_RFCBID_TYP     RFCTYPE_INT

}
RFCIE;

static RFC_UNICODE_TYPE_ELEMENT typeOfRfcIE[] =
{
{ cU("rfcaid"), RFCIE_RFCAID_TYP,    0,   4,  20,   4,  24,   4,  32 },
{ cU("rfcbid"), RFCIE_RFCBID_TYP,    0,   4,  20,   4,  24,   4,  32 }
};

#define ENTRIESIE( tab ) ( sizeofR(tab)/sizeofR((tab)[0]) )

RFCIE   imiestruct,
          exiestruct;

//.....

static RFC_RC DLL_CALL_BACK_FUNCTION GETSynDATA(RFC_HANDLE rfc_handle);
//...
rfc_char_t get_syn_dat[31] = iU("GETDATA"); // в скобках такое имя которое мы вызываем с САПа
//...


//Переходим в код ***.c где идет вызов нашей функции прописываем в инстал
static RFC_RC install(void)
{
//-------------------------------------------------------------------------------------//
/* Install Synchronization */
  fprintfU(stderr, cU("\n7.   RfcInstallFunction (%s) rfc_rc = "), get_syn_dat);

  rfc_rc = RfcInstallFunction(get_syn_dat,
                              (RFC_ONCALL) GETSynDATA,
                              NULL);
  fprintfU(stderr, cU("%d <= GET"), rfc_rc);

  if( rfc_rc != RFC_OK )
  {
    sprintfU(abort_text, cU("\nERROR: Install (%s) rfc_rc = %d"), get_syn_data, rfc_rc);
    function_abort(abort_text);
  }
//-------------------------------------------------------------------------------------//
}
static RFC_RC DLL_CALL_BACK_FUNCTION GETSynDATA(RFC_HANDLE rfc_handle)
{
//....
memsetR (&parameters[0], 0, sizeofR(parameters));

  /* Install structure 'RFC_DAT' */
rfc_rc = RfcInstallUnicodeStructure (cU("RFCIE"), /* там где typedef struct RFCIE */
   typeOfRfcIE,
   ENTRIESIE(typeOfRfcIE),
   0, NULL,
   &handleOfRfcIE );
if (rfc_rc != RFC_OK)
rfc_error (cU("RfcInstallStructure"));

  /* Importing Parameters */
parameters[0].name = cU("IMPORTSTRUCT");
parameters[0].nlen = 2;
parameters[0].addr = &imiestruct;
parameters[0].leng = RFCIE_LN;
parameters[0].type = handleOfRfcIE;
parameters[1].name = NULL;

/* Prepare internal table RFCIETABLE */
tables[0].name     = cU("RFCTABLE");
tables[0].nlen     = 8;
tables[0].type     = handleOfRfcIE;
tables[0].leng     = RFCIE_LN;
tables[0].itmode   = RFC_ITMODE_BYREFERENCE;
tables[1].name     = NULL;

    /* receive data */
    fprintfU (stderr, cU("\n<==  RfcGetData               rfc_rc = "));
    rfc_rc = RfcGetData (rfc_handle,
parameters,
tables);
   
    fprintfU (stderr, "%d", rfc_rc);

    if (rfc_rc != RFC_OK)
     rfc_error (cU("RfcGetData"));

/* Get specific info of this RFC connection*/
/* Echo structure */
exiestruct = imiestruct;

//...
retcode = SQLConnect .......
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLAllocHandle (SQL_HANDLE_STMT, hDBCSQL, &hSqlStmt);

// bind---------------
//.....
while ((retcode = SQLFetch(hSqlStmt)) == SQL_SUCCESS)
{
//insert data into table--------------------
/* New structure value */
imiestruct.rfcaid = aid;
imiestruct.rfcbid = bid;
/* Append into table 'RFCIETABLE' */
lineleng = ItLeng (tables[0].ithandle);
ptr = (rfc_char_t *) ItAppLine(tables[0].ithandle);
if (ptr == NULL)
rfc_error(cU("ItAppLine"));
memcpyR ((void *)ptr, &imiestruct, lineleng);
//end insert data into table----------------
}
         }
SQLFreeConnect (hDBCSQL); // Free the allocated connection handle
SQLFreeEnv (hEnvSQL); // Free the allocated ODBC environment handle
//......
rfc_rc = RfcSendData (rfc_handle,
  parameters,
  tables
);
//....
return rfc_rc;

}


Я вставил основные важные моменты, если кому есть что добавить - пожалуйста...
Конечно я не проверял, может будет работать и без экспорта структуры с САПа и достаточно того, что он описан в С/С++ - просто уже не было времени на эксперименты...
Назва: Re: RFC через ODBC используя C++
Відправлено: Uukrul від Лютий 14, 2012, 03:43:21 ПП
Цитата: Nexus від Травень 24, 2011, 10:10:39 ДП
(if you are SAP customer you can find it on http://service.sap.com/swdc under Patches for My Company's Application Components - SAP RFC SDK)
Типа если нет доступов: NW SAP RFC SDK