Подключиться к Oracle из C++

sitev_ru
Дата: 13.11.2014 07:10:19
Необходимо подключиться к Oracle из C++. Покажите, плиз, работающий пример?
mayton
Дата: 13.11.2014 09:28:22
Ищи по ключевому слову OCI (Oracle Call Interface). Материалов - валом.
sitev_ru
Дата: 13.11.2014 09:40:22
mayton,

Я поэтому и пишу "подскажите РАБОТАЮЩИЙ пример", потому что толком не нашёл работающего (хотя может я плохо разбираюсь в сборке готовых проектов)...

Перепробывал несколько примеров и везде столкнулся с проблемой компиляции. Например, вот этот:

#include <stdio.h>
#include <string.h>
#include <oci.h>

void checkerr(OCIError* err, sword status) {
    text errbuf[512];
    ub4 buflen;
    sb4 errcode;

    switch (status) {
    case OCI_SUCCESS:
        break;
    case OCI_SUCCESS_WITH_INFO:
        printf("Error - OCI_SUCCESS_WITH_INFO\n");
        break;
    case OCI_NEED_DATA:
        printf("Error - OCI_NEED_DATA\n");
        break;
    case OCI_NO_DATA:
        printf("Error - OCI_NO_DATA\n");
        break;
    case OCI_ERROR:
        OCIErrorGet(err, (ub4)1, (text *)NULL, &errcode,
            errbuf, (ub4) sizeof(errbuf), (ub4)OCI_HTYPE_ERROR);
        printf("Error - %s\n", errbuf);
        break;
    case OCI_INVALID_HANDLE:
        printf("Error - OCI_INVALID_HANDLE\n");
        break;
    case OCI_STILL_EXECUTING:
        printf("Error - OCI_STILL_EXECUTE\n");
        break;
    case OCI_CONTINUE:
        printf("Error - OCI_CONTINUE\n");
        break;
    default:
        break;
    }
}


void parse_connect_string(
    char* connect_str,  /* in   */
    text  username[30], /* out  */
    text  password[30], /* out  */
    text  dbname[30]  /* out  */
    ) {

    username[0] = 0;
    password[0] = 0;
    dbname[0] = 0;

    char* to = (char*)username;

    while (*connect_str) {
        if (*connect_str == '/') {
            *to = 0;
            to = (char*)password;
            connect_str++;
            continue;
        }
        if (*connect_str == '@') {
            *to = 0;
            to = (char*)dbname;
            connect_str++;
            continue;
        }
        *to = *connect_str;
        to++;
        connect_str++;
    }
    *to = 0;
}

int main(int argc, char* argv[]) {
    /*  (void) OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)           0,
    (dvoid * (*)(dvoid *, size_t))         0,
    (dvoid * (*)(dvoid *, dvoid *, size_t))0,
    (void (*)(dvoid *, dvoid *))           0 ); */



    /* The environment handle defines a context in which all OCI functions are
    invoked. Each environment handle contains a memory cache, which allows for
    fast memory access. All memory allocation under the environment handle is
    done from this cache. Access to the cache is serialized if multiple
    threads try to allocate memory under the same environment handle. When
    multiple threads share a single environment handle, they may block on
    access to the cache. The environment handle is passed as the parent
    parameter to the OCIHandleAlloc() call to allocate all other handle types.
    Bind and define handles are allocated implicitly.
    */
    OCIEnv*       env;

    /* The error handle is passed as a parameter to most OCI calls. The error
    handle maintains information about errors that occur during an OCI
    operation. If an error occurs in a call, the error handle can be passed to
    OCIErrorGet() to obtain additional information about the error that
    occurred. Allocating the error handle is one of the first steps in an OCI
    application because most OCI calls require an error handle as one of its
    parameters. */
    OCIError*     err;

    OCIServer*    srv;
    OCISvcCtx*    svc;
    OCISession*   ses;

    text          username[30];
    text          password[30];
    text          dbname[30];

    sword         r;

    if (argc < 2) {
        printf("usage %s username/password[@dbname]\n");
        return -1;
    }

    parse_connect_string(argv[1], username, password, dbname);

    env = 0;
    err = 0;
    srv = 0;
    svc = 0;
    ses = 0;

    int len = 0;

    r = OCIEnvCreate(&env, OCI_DEFAULT, 0, 0, 0, 0, 0, 0);

    if (r != OCI_SUCCESS)  {
        printf("OCIEnvCreate failed!\n");
        goto clean_up;
    }

    OCIHandleAlloc(env, (dvoid**)&err, OCI_HTYPE_ERROR, 0, 0);
    OCIHandleAlloc(env, (dvoid**)&srv, OCI_HTYPE_SERVER, 0, 0);
    OCIHandleAlloc(env, (dvoid**)&svc, OCI_HTYPE_SVCCTX, 0, 0);
    OCIHandleAlloc(env, (dvoid**)&ses, OCI_HTYPE_SESSION, 0, 0);

    len = strlen((char*)dbname);
    r = OCIServerAttach(srv, err, dbname, len, (ub4)OCI_DEFAULT);
    if (r != OCI_SUCCESS) {
        checkerr(err, r);
        goto clean_up;
    }

    /* set attribute server context in the service context */
    OCIAttrSet(svc, OCI_HTYPE_SVCCTX, srv, 0, OCI_ATTR_SERVER, err);

    OCIAttrSet(ses, OCI_HTYPE_SESSION, username, strlen((char*)username), OCI_ATTR_USERNAME, err);
    OCIAttrSet(ses, OCI_HTYPE_SESSION, password, strlen((char*)password), OCI_ATTR_PASSWORD, err);

    r = OCISessionBegin(svc, err, ses, OCI_CRED_RDBMS, OCI_DEFAULT);
    checkerr(err, r);


clean_up:

    if (env) OCIHandleFree(env, OCI_HTYPE_ENV);
    if (err) OCIHandleFree(err, OCI_HTYPE_ERROR);
    if (srv) OCIHandleFree(srv, OCI_HTYPE_SERVER);
    if (svc) OCIHandleFree(svc, OCI_HTYPE_SVCCTX);

    OCITerminate(OCI_DEFAULT);

    return 0;
}


Выдаёт ошибки:
Description Resource    Path    Location    Type
make: *** [oci6linux] Error 1   oci6linux           C/C++ Problem
undefined reference to `OCIAttrSet' oci6linux.cpp   /oci6linux/src  line 154    C/C++ Problem
undefined reference to `OCIAttrSet' oci6linux.cpp   /oci6linux/src  line 156    C/C++ Problem
undefined reference to `OCIAttrSet' oci6linux.cpp   /oci6linux/src  line 157    C/C++ Problem
undefined reference to `OCIEnvCreate'   oci6linux.cpp   /oci6linux/src  line 134    C/C++ Problem
undefined reference to `OCIErrorGet'    oci6linux.cpp   /oci6linux/src  line 29 C/C++ Problem
undefined reference to `OCIHandleAlloc' oci6linux.cpp   /oci6linux/src  line 141    C/C++ Problem
undefined reference to `OCIHandleAlloc' oci6linux.cpp   /oci6linux/src  line 142    C/C++ Problem
undefined reference to `OCIHandleAlloc' oci6linux.cpp   /oci6linux/src  line 143    C/C++ Problem
undefined reference to `OCIHandleAlloc' oci6linux.cpp   /oci6linux/src  line 144    C/C++ Problem
undefined reference to `OCIHandleFree'  oci6linux.cpp   /oci6linux/src  line 165    C/C++ Problem
undefined reference to `OCIHandleFree'  oci6linux.cpp   /oci6linux/src  line 166    C/C++ Problem
undefined reference to `OCIHandleFree'  oci6linux.cpp   /oci6linux/src  line 167    C/C++ Problem
undefined reference to `OCIHandleFree'  oci6linux.cpp   /oci6linux/src  line 168    C/C++ Problem
undefined reference to `OCIServerAttach'    oci6linux.cpp   /oci6linux/src  line 147    C/C++ Problem
undefined reference to `OCISessionBegin'    oci6linux.cpp   /oci6linux/src  line 159    C/C++ Problem
undefined reference to `OCITerminate'   oci6linux.cpp   /oci6linux/src  line 170    C/C++ Problem


Что не так?
Basil A. Sidorov
Дата: 13.11.2014 09:49:58
Oracle Instant Client.
Среди загрузок есть SDK с заголовочными файлами, библиотеками и примерами.
sitev_ru
Дата: 13.11.2014 10:10:57
Basil A. Sidorov,

загружал, пробывал... давайте ещё раз попробуем вместе??? может не так что-то делаю...

скачал файлики rpm, установил их в линуксе (у меня CentOS)

Пример, лежит здесь: /usr/share/oracle/10.2.0.5/client64
Инслуды здесь: /usr/include/oracle/10.2.0.5/client64
Библиотеки здесь: /usr/lib/oracle/10.2.0.5/client64

Компилю:
gcc cdemo81.c -I/usr/include/oracle/10.2.0.5/client64 -L/usr/lib/oracle/10.2.0.5/client64

/tmp/ccqr5hRx.o: In function `main':
cdemo81.c:(.text+0xd7): undefined reference to `OCIEnvCreate'
cdemo81.c:(.text+0x128): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x151): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x17a): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x1a3): undefined reference to `OCIServerAttach'
cdemo81.c:(.text+0x1d3): undefined reference to `OCIAttrSet'
cdemo81.c:(.text+0x1fc): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x238): undefined reference to `OCIAttrSet'
cdemo81.c:(.text+0x274): undefined reference to `OCIAttrSet'
cdemo81.c:(.text+0x29f): undefined reference to `OCISessionBegin'
cdemo81.c:(.text+0x2e7): undefined reference to `OCIAttrSet'
cdemo81.c:(.text+0x310): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x351): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x3a6): undefined reference to `OCIStmtPrepare'
cdemo81.c:(.text+0x41a): undefined reference to `OCIDefineByPos'
cdemo81.c:(.text+0x473): undefined reference to `OCIStmtExecute'
cdemo81.c:(.text+0x505): undefined reference to `OCIHandleAlloc'
cdemo81.c:(.text+0x572): undefined reference to `OCIStmtPrepare'
cdemo81.c:(.text+0x5c7): undefined reference to `OCIStmtPrepare'
cdemo81.c:(.text+0x659): undefined reference to `OCIBindByName'
cdemo81.c:(.text+0x6e6): undefined reference to `OCIBindByName'
cdemo81.c:(.text+0x76f): undefined reference to `OCIBindByName'
cdemo81.c:(.text+0x7f8): undefined reference to `OCIBindByName'
cdemo81.c:(.text+0x881): undefined reference to `OCIBindByName'
cdemo81.c:(.text+0x92e): undefined reference to `OCIBindByPos'
cdemo81.c:(.text+0x9e9): undefined reference to `OCIDefineByPos'
cdemo81.c:(.text+0xc18): undefined reference to `OCIStmtExecute'
cdemo81.c:(.text+0xcd1): undefined reference to `OCIStmtExecute'
cdemo81.c:(.text+0xd6e): undefined reference to `OCIStmtExecute'
cdemo81.c:(.text+0xdea): undefined reference to `OCITransCommit'
/tmp/ccqr5hRx.o: In function `checkerr':
cdemo81.c:(.text+0xf30): undefined reference to `OCIErrorGet'
/tmp/ccqr5hRx.o: In function `cleanup':
cdemo81.c:(.text+0xf9b): undefined reference to `OCIHandleFree'
collect2: ld returned 1 exit status


Как исправить ошибки???
Basil A. Sidorov
Дата: 13.11.2014 10:33:10
Компоновщику нужны имена файлов, в которых расположена та или иная библиотечная функция.
Только после этого он пробежится по списку каталогов из LIB.
Dimitry Sibiryakov
Дата: 13.11.2014 11:59:45

sitev_ru
Как исправить ошибки???

Изучить основы работы с кмпилятором С. В частности - стадию линковки. Ещё точнее -
указание библиотек.

Posted via ActualForum NNTP Server 1.5

sitev_ru
Дата: 13.11.2014 12:14:14
gcc cdemo81.c -I/usr/include/oracle/10.2.0.5/client64 -L/usr/lib/oracle/10.2.0.5/client64 -loci


так? почему то не работает...
mayton
Дата: 13.11.2014 12:40:02
sitev_ru
gcc cdemo81.c -I/usr/include/oracle/10.2.0.5/client64 -L/usr/lib/oracle/10.2.0.5/client64 -loci


так? почему то не работает...

Когда ты говоришь - не работает - то должен публиковать сообщение об ошибке. Если код или месседж
изменяется то мы видим прогресс в решении проблемы.

Если ты просто горестно сообщаешь о том что "всё пропало" то у нас есть только эмоции.

Можем сочувствовать и также охать.
sitev_ru
Дата: 13.11.2014 12:47:33
mayton,

gcc cdemo81.c -I/usr/include/oracle/10.2.0.5/client64 -L/usr/lib/oracle/10.2.0.5/client64 -lociei

Лежит там такой файлик libociei, но всё равно выдаёт:

cannot find -lociei