在rhel8上使用soci连接oracle和postgresql

2022-07-23  本文已影响0人  路长心自远

软件安装

安装oracle客户端

连接oracle需要oracle的客户端软件或者oracle服务器软件。本例以oracle客户端为例。

rpm -ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm  oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm  oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm

安装完毕之后,需要配置环境变量

[baby@localhost ~]$ cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib

ORACLE_HOME=/usr/lib/oracle/12.2/client64
export ORACLE_HOME
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ORACLE_HOME}/lib
export TNS_ADMIN=$ORACLE_HOME/network/admin

安装postgrersql

rpm -ivh postgresql12-docs-12.7-2PGDG.rhel8.x86_64.rpm  postgresql12-libs-12.7-2PGDG.rhel8.x86_64.rpm postgresql12-12.7-2PGDG.rhel8.x86_64.rpm postgresql12-server-12.7-2PGDG.rhel8.x86_64.rpm
  postgresql12-contrib-12.7-2PGDG.rhel8.x86_64.rpm

另外,还需要一个开发包 postgresql12-devel-12.7-2PGDG.rhel8.x86_64.rpm,安装此开发包,需要各种第三方依赖,为了省事,此处仅是把该rpm包解开。

rpm2cpio postgresql12-devel-12.7-2PGDG.rhel8.x86_64.rpm | cpio -div

安装boost_1_53_0(选装)

cd /home/baby/Downloads/boost_1_53_0/
./bootstrap.sh
./b2 install --with=all

安装soci

cd /home/baby/Downloads/soci-4.0.2
mkdir build
cd bulid

以下这个命令,是编译出连接oracle、postgresl和sqlite3的动态库。参考了官方文档: http://soci.sourceforge.net/doc/release/4.0/installation/

cmake -G "Unix Makefiles" -DWITH_BOOST=OFF -DSOCI_CXX11=ON -DWITH_ORACLE=ON -DORACLE_INCLUDE_DIR=/u01/app/oracle/product/11.2.0/xe/rdbms/public/ -DORACLE_LIBRARIES=/u01/app/oracle/product/11.2.0/xe/lib -DSOCI_ORACLE=ON -DWITH_POSTGRESQL=ON -DPOSTGRESQL_INCLUDE_DIR=/usr/pgsql-12/include -DPOSTGRESQL_LIBRARY=/usr/pgsql-12/lib -DPOSTGRESQL_LIBRARIES=pq -DSOCI_POSTGRESQL=ON -DWITH_SQLITE3=ON -DSQLITE3_INCLUDE_DIR=/usr/include/ -DSQLITE3_LIBRARIES=/usr/lib64/ ..

make

注意:上述命令中的路径需要是正确的。然后会在/home/baby/Downloads/soci-4.0.2/build/lib中生成如下几个文件:
libsoci_core.a libsoci_empty.so@ libsoci_mysql.so.4.0@ libsoci_odbc.so.4.0.2* libsoci_postgresql.a libsoci_sqlite3.so@
libsoci_core.so@ libsoci_empty.so.4.0@ libsoci_mysql.so.4.0.2* libsoci_oracle.a libsoci_postgresql.so@ libsoci_sqlite3.so.4.0@
libsoci_core.so.4.0@ libsoci_empty.so.4.0.2* libsoci_odbc.a libsoci_oracle.so@ libsoci_postgresql.so.4.0@ libsoci_sqlite3.so.4.0.2*
libsoci_core.so.4.0.2* libsoci_mysql.a libsoci_odbc.so@ libsoci_oracle.so.4.0@ libsoci_postgresql.so.4.0.2*
libsoci_empty.a libsoci_mysql.so@ libsoci_odbc.so.4.0@ libsoci_oracle.so.4.0.2* libsoci_sqlite3.a

测试代码

连接oracle的例子

//============================================================================
// Name        : soci_oracle.cpp
/*

g++ -std=c++0x -I/home/baby/tools/soci-4.0.2/include/soci -I/home/baby/tools/soci-4.0.2/include -I/home/baby/tools/soci-4.0.2/build/include -g -L/home/baby/tools/soci-4.0.2/build/lib -lsoci_oracle -lsoci_core -o soci_oracle soci_oracle.cpp

*/
//============================================================================

#include <soci.h>
#include <iostream>
#include <string>

using namespace soci;
using std::string;

void create_table()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");
        sql << "create table Person(id number, name varchar2(50))";
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void drop_table()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");

        sql << "drop table person";
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void insert_table()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");

        int id(100);
        string name("Bjarne");
        sql << "insert into Person values (:ID, :NAME)", use(id), use(name);
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void select_table()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");

        int id2;
        string name2;
        sql << "select id, name from Person", into(id2), into(name2);
        std::cout << name2 << " has id " << id2 << std::endl;
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void select_table_conn_pool()
{
    try
    {
        soci::connection_pool pool(10);
        for (int i = 0; i < 10; i++)
        {
            soci::session &sql = pool.at(i);
            sql.open("oracle", "service=xe user=baby password=baby1234");
        }
        soci::session one_session(pool);
        int id2;
        string name2;
        one_session << "select id, name from Person", into(id2), into(name2);
        std::cout << name2 << " has id " << id2 << std::endl;
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

/*
 CREATE TABLE TEST_BLOB
 (ID NUMBER(5),
 NAME varchar2(100),
 BLOBATTR blob);
 * */
void select_blob()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");
        std::string sql_str(
            "select name, BLOBATTR from TEST_BLOB where ID=:id");

        soci::blob blob_attr(sql);
        std::string name;
        int id = 1;
        sql << sql_str, into(name), into(blob_attr), soci::use(id);
        std::cout << " name " << name << std::endl;
        std::cout << " blob_attr.get_len " << blob_attr.get_len() << std::endl;
        std::cout << " blob_attr.get_len " << blob_attr.get_len() << std::endl;
        char attr[20] = {0};
        blob_attr.read_from_start(attr, blob_attr.get_len());
        for (int i = 0; i < blob_attr.get_len(); i++)
        {
            std::cout << "value is " << attr[i] << std::endl;
        }
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

void update_blob()
{
    try
    {
        soci::session sql("oracle", "service=xe user=baby password=baby1234");
        std::string sql_str(
            "select name, BLOBATTR from TEST_BLOB where ID=1 for update");

        soci::blob blob_attr(sql);
        std::string name;
        sql << sql_str, into(name), into(blob_attr);
        std::cout << " name " << name << std::endl;
        std::cout << " blob_attr.get_len " << blob_attr.get_len() << std::endl;
        std::cout << " blob_attr.get_len " << blob_attr.get_len() << std::endl;
        char attr[20] = {0};
        blob_attr.read_from_start(attr, blob_attr.get_len());
        for (int i = 0; i < blob_attr.get_len(); i++)
        {
            std::cout << "value is " << attr[i] << std::endl;
        }

        attr[19] = 'D';
        blob_attr.write_from_start(attr, 20);
        sql.commit();
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        std::cout << "parameter error" << std::endl;
        std::cout << "C create table" << std::endl;
        std::cout << "I insert table" << std::endl;
        std::cout << "S select table" << std::endl;
        std::cout << "SP select table using connection pool" << std::endl;
        std::cout << "D drop table" << std::endl;
        std::cout << "SB select blob" << std::endl;
        return 1;
    }
    std::string cmd(argv[1]);
    if (cmd == "C")
    {
        create_table();
    }
    if (cmd == "I")
    {
        insert_table();
    }
    if (cmd == "S")
    {
        select_table();
    }
    if (cmd == "SP")
    {
        select_table_conn_pool();
    }

    if (cmd == "D")
    {
        drop_table();
    }

    if (cmd == "SB")
    {
        select_blob();
    }

    if (cmd == "UB")
    {
        update_blob();
    }
    return 0;
}

在编译的时候,使用C++11 include文件要包含好。lib连接路径要配置正确,需要的库有libsoci-oracle,libsoci-core
在运行的时候,需要配置LD_LIBRARY_PATH的路径,把libsoci-oracle,libsoci-core等所在的目录包含进来。

连接postgresql的例子

在编译的时候,使用C++11 include文件要包含好。lib连接路径要配置正确,需要的库有libsoci-postgresql,libsoci-core
在运行的时候,需要配置LD_LIBRARY_PATH的路径,把libsoci-postgresql,libsoci-core等所在的目录包含进来。

连接sqlite的测试

上一篇下一篇

猜你喜欢

热点阅读