在rhel8上使用soci连接oracle和postgresql
软件安装
安装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等所在的目录包含进来。