mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-02 15:24:57 +01:00
Oracle ODBC fixes
This commit is contained in:
parent
bbf30dc674
commit
494579542f
@ -158,7 +158,6 @@ private:
|
||||
bool _prepared;
|
||||
mutable std::size_t _affectedRowCount;
|
||||
bool _canCompile;
|
||||
bool _isPostgres;
|
||||
bool _insertHint;
|
||||
};
|
||||
|
||||
|
@ -99,9 +99,7 @@ public:
|
||||
Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction,
|
||||
bool isPostgres
|
||||
);
|
||||
DataExtraction dataExtraction);
|
||||
/// Creates the Preparator.
|
||||
|
||||
Preparator(const Preparator& other);
|
||||
|
@ -135,18 +135,11 @@ void ODBCMetaColumn::init()
|
||||
|
||||
case SQL_NUMERIC:
|
||||
case SQL_DECIMAL:
|
||||
if (0 == _columnDesc.decimalDigits)
|
||||
{
|
||||
#ifdef POCO_64_BIT
|
||||
setType(MetaColumn::FDT_INT64);
|
||||
#else
|
||||
setType(MetaColumn::FDT_INT32);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
setType(MetaColumn::FDT_DOUBLE);
|
||||
}
|
||||
// Oracle has no INTEGER type - it's essentially NUMBER with 38 whole and
|
||||
// 0 fractional digits. It also does not recognize SQL_BIGINT type,
|
||||
// so the workaround here is to hardcode it to 32 bit integer
|
||||
if (0 == _columnDesc.decimalDigits) setType(MetaColumn::FDT_INT32);
|
||||
else setType(MetaColumn::FDT_DOUBLE);
|
||||
break;
|
||||
|
||||
case SQL_REAL:
|
||||
|
@ -45,7 +45,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
||||
_prepared(false),
|
||||
_affectedRowCount(0),
|
||||
_canCompile(true),
|
||||
_isPostgres(false),
|
||||
_insertHint(false)
|
||||
{
|
||||
int queryTimeout = rSession.queryTimeout();
|
||||
@ -64,7 +63,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
||||
std::string serverString;
|
||||
serverString.resize(static_cast<std::size_t>(t) + 2);
|
||||
r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t);
|
||||
_isPostgres = (!Utility::isError(r) && Poco::toUpperInPlace(serverString).find("PSQLODBC") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +150,7 @@ bool ODBCStatementImpl::addPreparator(bool addAlways)
|
||||
|
||||
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
||||
|
||||
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _isPostgres);
|
||||
prep = new Preparator(_stmt, statement, maxFieldSize, ext);
|
||||
}
|
||||
else
|
||||
prep = new Preparator(*_preparations[0]);
|
||||
@ -307,14 +305,13 @@ bool ODBCStatementImpl::nextResultSet()
|
||||
if (SQL_NO_DATA == ret)
|
||||
return false;
|
||||
|
||||
if (Utility::isError(ret)) {
|
||||
if (Utility::isError(ret))
|
||||
throw StatementException(_stmt, "SQLMoreResults()");
|
||||
}
|
||||
|
||||
// need to remove old bindings, as Sybase doesn't like old ones
|
||||
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND))) {
|
||||
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND)))
|
||||
throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,7 @@ namespace ODBC {
|
||||
Preparator::Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction,
|
||||
bool isPostgres) :
|
||||
DataExtraction dataExtraction) :
|
||||
_rStmt(rStmt),
|
||||
_maxFieldSize(maxFieldSize),
|
||||
_dataExtraction(dataExtraction)
|
||||
@ -38,9 +37,8 @@ Preparator::Preparator(const StatementHandle& rStmt,
|
||||
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
|
||||
throw StatementException(_rStmt);
|
||||
// PostgreSQL error swallowing workaround:
|
||||
// Postgres may execute a statement with sintax error fine,
|
||||
// but would return error once num of columns requested!
|
||||
if (isPostgres)
|
||||
// Postgres may execute a statement with syntax error fine,
|
||||
// but will return error later
|
||||
{
|
||||
SQLSMALLINT t = 0;
|
||||
SQLRETURN r = SQLNumResultCols(rStmt, &t);
|
||||
|
@ -41,7 +41,7 @@ using Poco::DynamicAny;
|
||||
using Poco::DateTime;
|
||||
|
||||
|
||||
#define ORACLE_ODBC_DRIVER "Oracle in OraClient12Home1_32bit"//XE"
|
||||
#define ORACLE_ODBC_DRIVER "Oracle in OraDB12Home1"//XE"
|
||||
#define ORACLE_DSN "PocoDataOracleTest"
|
||||
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
||||
#define ORACLE_PORT "1521"
|
||||
@ -775,13 +775,22 @@ void ODBCOracleTest::recreateStringsTable()
|
||||
|
||||
void ODBCOracleTest::recreateFloatsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str NUMBER)", now; }
|
||||
dropObject("TABLE", ExecUtil::floats());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::floats() <<" (str NUMBER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::recreateDoublesTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::doubles());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::doubles() << " (str NUMBER)", now; }
|
||||
catch (ConnectionException& ce) { std::cout << ce.toString() << std::endl; fail("recreateFloatsTable()"); }
|
||||
catch (StatementException& se) { std::cout << se.toString() << std::endl; fail("recreateFloatsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::recreateTuplesTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::tuples());
|
||||
@ -815,10 +824,13 @@ void ODBCOracleTest::recreateAnysTable()
|
||||
void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::nulltest());
|
||||
try { *_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)",ExecUtil::nulltest(),
|
||||
try
|
||||
{
|
||||
*_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
|
||||
notNull,
|
||||
notNull,
|
||||
notNull), now; }
|
||||
notNull), now;
|
||||
}
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); }
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
void recreateStringsTable();
|
||||
void recreateIntsTable();
|
||||
void recreateFloatsTable();
|
||||
void recreateDoublesTable();
|
||||
void recreateTuplesTable();
|
||||
void recreateVectorsTable();
|
||||
void recreateAnysTable();
|
||||
|
@ -3015,7 +3015,8 @@ void SQLExecutor::notNulls(const std::string& sqlState)
|
||||
{
|
||||
session() << "INSERT INTO "<< ExecUtil::nulltest() << " (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
|
||||
fail ("must fail");
|
||||
}catch (StatementException& se)
|
||||
}
|
||||
catch (StatementException& se)
|
||||
{
|
||||
//double check if we're failing for the right reason
|
||||
//default sqlState value is "23502"; some drivers report "HY???" codes
|
||||
|
Loading…
x
Reference in New Issue
Block a user