We have JDBC in Java… and SOCI in C++… Well, it’s not so easy as it should be. To build with cmake:
1 2 3 4 |
# mkdir ../build # cd ../build # set ORACLE_HOME=C:\oraclexe\app\oracle\product\10.2.0\server # cmake -G "Visual Studio 9 2008" -DMYSQL_INCLUDE_DIR="C:\Program Files\MySQL\MySQL Server 5.5\include" -DMYSQL_LIBRARIES="C:\Program Files\MySQL\MySQL Server 5.5\lib\libmysql.lib" ../soci-3.2.3 |
The documents seem outdated, many options do not work. Just managed to figure out from the *.cmake source files. You can also download the oracle instant client SDK, and re-arrange the directory structure for build.
Code snippet I extracted from its unit tests:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include "soci.h" #include "soci-mysql.h" //#include "soci-oracle.h" #include <ctime> #include <string> #include <iostream> #include <sstream> using namespace std; int main() { try { soci::session sql(soci::mysql, "host=192.168.1.101 db=mysql user=root password=111111"); //soci::session sql(soci::oracle, "service=192.168.1.102/ORCL user=sys password=111111"); soci::row v; /* comma operator is overloaded here.. */ soci::statement st = (sql.prepare << "SELECT * FROM user", into(v)); //soci::statement st = (sql.prepare << "SELECT * FROM SYS.USER$", into(v)); st.execute(true); /* with data exchange */ unsigned int num_fields = v.size(); cout << "fields: " << num_fields << endl; num_fields = (num_fields <= 9) ? num_fields : 9; unsigned long num_rows = (unsigned long)st.get_affected_rows(); cout << "rows: " << num_rows << endl; for (size_t i = 0; i < num_fields; ++i) { const soci::column_properties &props = v.get_properties(i); cout << props.get_name() << '\t'; } cout << endl; do { stringstream ss; for (size_t i = 0; i < num_fields; ++i) { if (v.get_indicator(i) == soci::i_null) { ss << "NULL"; break; } const soci::column_properties &props = v.get_properties(i); switch (props.get_data_type()) { case soci::dt_string: ss << v.get<string>(i); break; case soci::dt_double: ss << v.get<double>(i); break; case soci::dt_integer: ss << v.get<int>(i); break; case soci::dt_long_long: ss << v.get<long long>(i); break; case soci::dt_unsigned_long_long: ss << v.get<unsigned long long>(i); break; case soci::dt_date: tm dt = v.get<tm>(i); ss << asctime(&dt); break; } ss << '\t'; } cout << ss.str() << endl; } while (st.fetch()); } catch (soci::soci_error &e) { cerr << "Error: " << e.what() << endl; } return 0; } |
Updated Apr 20, 2015:
1. Under RHEL5/CentOS5, I got errors like:
1 |
./test_oracle: error while loading shared libraries: /home/gonwan/oracle11_64/lib/libnnz11.so: cannot restore segment prot after reloc: Permission denied |
It’s due to SELinux security feature. Simply workaround it with:
1 |
# chcon -t texrel_shlib_t *.so* |
2. Oracle uses oraociei11.dll
or libociei.so
for client data. They are both large files(110+MB), since they support multiple languages. Instead, you can use oraociicus11.dll
(30+MB) or libociicus.so
(10-MB). These files contain only English support.