mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-31 16:04:27 +02:00
batch statements (multiple results) support
This commit is contained in:
parent
ae34e0ff3b
commit
95c5230389
Data
ODBC
include/Poco/Data/ODBC
src
testsuite/src
include/Poco/Data
src
@ -126,6 +126,9 @@ private:
|
||||
void makeInternalExtractors();
|
||||
/// Creates internal extractors if none were supplied from the user.
|
||||
|
||||
bool isStoredProcedure() const;
|
||||
/// Returns true if SQL is a stored procedure call.
|
||||
|
||||
void doPrepare();
|
||||
/// Prepares placeholders for data returned by statement.
|
||||
/// It is called during statement compilation for SQL statements
|
||||
|
@ -199,6 +199,9 @@ private:
|
||||
void prepareImpl(std::size_t pos);
|
||||
/// Utility function to prepare Any and DynamicAny
|
||||
|
||||
void resize() const;
|
||||
/// Resize the values and lengths vectors.
|
||||
|
||||
template <typename T>
|
||||
void preparePOD(std::size_t pos, SQLSMALLINT valueType)
|
||||
{
|
||||
|
@ -284,25 +284,17 @@ bool ODBCStatementImpl::hasNext()
|
||||
|
||||
if (!nextRowReady())
|
||||
{
|
||||
try
|
||||
{
|
||||
activateNextDataSet();
|
||||
} catch (InvalidAccessException&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try { activateNextDataSet(); }
|
||||
catch (InvalidAccessException&)
|
||||
{ return false; }
|
||||
|
||||
try { checkError(SQLMoreResults(_stmt)); }
|
||||
catch (NoDataException&)
|
||||
{ return false; }
|
||||
|
||||
addPreparation();
|
||||
doPrepare();
|
||||
fixupExtraction();
|
||||
|
||||
try
|
||||
{
|
||||
checkError(SQLMoreResults(_stmt));
|
||||
} catch (NoDataException&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
makeStep();
|
||||
}
|
||||
else if (Utility::isError(_nextResponse))
|
||||
@ -408,4 +400,13 @@ void ODBCStatementImpl::fillColumns()
|
||||
}
|
||||
|
||||
|
||||
bool ODBCStatementImpl::isStoredProcedure() const
|
||||
{
|
||||
std::string str = toString();
|
||||
if (trimInPlace(str).size() < 2) return false;
|
||||
|
||||
return ('{' == str[0] && '}' == str[str.size()-1]);
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
@ -62,6 +62,7 @@ Preparation::Preparation(const Preparation& other):
|
||||
_maxFieldSize(other._maxFieldSize),
|
||||
_dataExtraction(other._dataExtraction)
|
||||
{
|
||||
resize();
|
||||
}
|
||||
|
||||
|
||||
@ -79,21 +80,23 @@ Preparation::~Preparation()
|
||||
|
||||
std::size_t Preparation::columns() const
|
||||
{
|
||||
if (_pValues.empty())
|
||||
{
|
||||
SQLSMALLINT nCol = 0;
|
||||
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) &&
|
||||
0 != nCol)
|
||||
{
|
||||
_pValues.resize(nCol, 0);
|
||||
_pLengths.resize(nCol, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (_pValues.empty()) resize();
|
||||
return _pValues.size();
|
||||
}
|
||||
|
||||
|
||||
void Preparation::resize() const
|
||||
{
|
||||
SQLSMALLINT nCol = 0;
|
||||
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) &&
|
||||
0 != nCol)
|
||||
{
|
||||
_pValues.resize(nCol, 0);
|
||||
_pLengths.resize(nCol, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Poco::Any& Preparation::operator [] (std::size_t pos)
|
||||
{
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
|
@ -1201,6 +1201,22 @@ void ODBCDB2Test::testDynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void ODBCDB2Test::testMultipleResults()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreatePersonTable();
|
||||
_pSession->setFeature("autoBind", bindValues[i]);
|
||||
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||
_pExecutor->multipleResults();
|
||||
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
|
||||
{
|
||||
try
|
||||
@ -1350,7 +1366,11 @@ bool ODBCDB2Test::canConnect(const std::string& driver, const std::string& dsn)
|
||||
{
|
||||
std::cout << "DSN found: " << itDSN->first
|
||||
<< " (" << itDSN->second << ')' << std::endl;
|
||||
format(_dbConnString, "DSN=%s", dsn);
|
||||
format(_dbConnString,
|
||||
"DSN=%s;"
|
||||
"Uid=db2admin;"
|
||||
"Pwd=db2admin;",
|
||||
dsn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1470,6 +1490,7 @@ CppUnit::Test* ODBCDB2Test::suite()
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testAsync);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testMultipleResults);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -132,6 +132,8 @@ public:
|
||||
void testAny();
|
||||
void testDynamicAny();
|
||||
|
||||
void testMultipleResults();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
@ -108,6 +108,9 @@ void ODBCMySQLTest::testBareboneODBC()
|
||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
||||
|
||||
/*
|
||||
MySQL supports batch statements as of 3.51.18
|
||||
http://bugs.mysql.com/bug.php?id=7445
|
||||
|
||||
tableCreateString = "CREATE TABLE Test "
|
||||
"(First VARCHAR(30),"
|
||||
@ -118,6 +121,7 @@ void ODBCMySQLTest::testBareboneODBC()
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -989,6 +993,27 @@ void ODBCMySQLTest::testDynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void ODBCMySQLTest::testMultipleResults()
|
||||
{
|
||||
/*
|
||||
MySQL supports batch statements as of 3.51.18
|
||||
http://bugs.mysql.com/bug.php?id=7445
|
||||
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreatePersonTable();
|
||||
_pSession->setFeature("autoBind", bindValues[i]);
|
||||
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||
_pExecutor->multipleResults();
|
||||
|
||||
i += 2;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
|
||||
{
|
||||
*_pSession << format("DROP %s IF EXISTS %s", type, name), now;
|
||||
@ -1239,6 +1264,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAsync);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testAny);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testMultipleResults);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -132,6 +132,8 @@ public:
|
||||
void testAny();
|
||||
void testDynamicAny();
|
||||
|
||||
void testMultipleResults();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
@ -131,17 +131,17 @@ void ODBCOracleTest::testBarebone()
|
||||
"Third NUMBER)";
|
||||
|
||||
*_pSession << "CREATE OR REPLACE "
|
||||
"PROCEDURE multiResultsProcedure(tmp1 OUT SYS_REFCURSOR, "
|
||||
"tmp2 OUT SYS_REFCURSOR,"
|
||||
"tmp3 OUT SYS_REFCURSOR,"
|
||||
"tmp4 OUT SYS_REFCURSOR,"
|
||||
"tmp5 OUT SYS_REFCURSOR) IS "
|
||||
"PROCEDURE multiResultsProcedure(ret1 OUT SYS_REFCURSOR, "
|
||||
"ret2 OUT SYS_REFCURSOR,"
|
||||
"ret3 OUT SYS_REFCURSOR,"
|
||||
"ret4 OUT SYS_REFCURSOR,"
|
||||
"ret5 OUT SYS_REFCURSOR) IS "
|
||||
"BEGIN "
|
||||
"OPEN tmp1 FOR SELECT * FROM Test WHERE First = '1';"
|
||||
"OPEN tmp2 FOR SELECT * FROM Test WHERE First = '2';"
|
||||
"OPEN tmp3 FOR SELECT * FROM Test WHERE First = '3';"
|
||||
"OPEN tmp4 FOR SELECT * FROM Test WHERE First = '4';"
|
||||
"OPEN tmp5 FOR SELECT * FROM Test WHERE First = '5';"
|
||||
"OPEN ret1 FOR SELECT * FROM Test WHERE First = '1';"
|
||||
"OPEN ret2 FOR SELECT * FROM Test WHERE First = '2';"
|
||||
"OPEN ret3 FOR SELECT * FROM Test WHERE First = '3';"
|
||||
"OPEN ret4 FOR SELECT * FROM Test WHERE First = '4';"
|
||||
"OPEN ret5 FOR SELECT * FROM Test WHERE First = '5';"
|
||||
"END multiResultsProcedure;" , now;
|
||||
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString,
|
||||
@ -1109,7 +1109,7 @@ void ODBCOracleTest::testStoredProcedureDynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::testStoredCursorProcedure()
|
||||
void ODBCOracleTest::testCursorStoredProcedure()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
@ -1251,7 +1251,7 @@ void ODBCOracleTest::testStoredFunction()
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::testStoredCursorFunction()
|
||||
void ODBCOracleTest::testCursorStoredFunction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
@ -1367,6 +1367,39 @@ void ODBCOracleTest::testDynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::testMultipleResults()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
|
||||
std::string sql = "CREATE OR REPLACE "
|
||||
"PROCEDURE multiResultsProcedure(paramAge1 IN NUMBER,"
|
||||
" paramAge2 IN NUMBER,"
|
||||
" ret1 OUT SYS_REFCURSOR, "
|
||||
" ret2 OUT SYS_REFCURSOR,"
|
||||
" ret3 OUT SYS_REFCURSOR) IS "
|
||||
"BEGIN "
|
||||
" OPEN ret1 FOR SELECT * FROM Person WHERE Age = paramAge1;"
|
||||
" OPEN ret2 FOR SELECT Age FROM Person WHERE FirstName = 'Bart';"
|
||||
" OPEN ret3 FOR SELECT * FROM Person WHERE Age = paramAge2;"
|
||||
"END multiResultsProcedure;";
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreatePersonTable();
|
||||
*_pSession << sql, now;
|
||||
_pSession->setFeature("autoBind", bindValues[i]);
|
||||
_pSession->setFeature("autoExtract", bindValues[i+1]);
|
||||
_pExecutor->multipleResults("{call multiResultsProcedure(?, ?)}");
|
||||
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ODBCOracleTest::dropObject(const std::string& type, const std::string& name)
|
||||
{
|
||||
try
|
||||
@ -1593,14 +1626,16 @@ bool ODBCOracleTest::init(const std::string& driver, const std::string& dsn)
|
||||
|
||||
_pExecutor = new SQLExecutor(driver + " SQL Executor", _pSession);
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
// Workaround:
|
||||
//
|
||||
// Barebone ODBC test is called initially for Oracle only.
|
||||
// Barebone ODBC test is called automatically on startup for Oracle.
|
||||
// The test framework does not exit cleanly if
|
||||
// Oracle tests are enabled (i.e. Oracle driver is found)
|
||||
// but no tests are executed.
|
||||
// The exact reason for this behavior is unknown at this time.
|
||||
testBarebone();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1661,11 +1696,11 @@ CppUnit::Test* ODBCOracleTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredCursorProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureAny);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredProcedureDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredCursorFunction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
||||
@ -1673,6 +1708,7 @@ CppUnit::Test* ODBCOracleTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testAsync);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testAny);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testMultipleResults);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -120,9 +120,9 @@ public:
|
||||
void testInternalStorageType();
|
||||
|
||||
void testStoredProcedure();
|
||||
void testStoredCursorProcedure();
|
||||
void testCursorStoredProcedure();
|
||||
void testStoredFunction();
|
||||
void testStoredCursorFunction();
|
||||
void testCursorStoredFunction();
|
||||
void testStoredProcedureAny();
|
||||
void testStoredProcedureDynamicAny();
|
||||
|
||||
@ -134,6 +134,8 @@ public:
|
||||
void testAny();
|
||||
void testDynamicAny();
|
||||
|
||||
void testMultipleResults();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
@ -123,7 +123,8 @@ void ODBCPostgreSQLTest::testBareboneODBC()
|
||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
|
||||
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
|
||||
|
||||
|
||||
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
|
||||
/*
|
||||
tableCreateString = "CREATE TABLE Test "
|
||||
"(First VARCHAR(30),"
|
||||
"Second INTEGER,"
|
||||
@ -133,6 +134,7 @@ void ODBCPostgreSQLTest::testBareboneODBC()
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||
_pExecutor->bareboneODBCMultiResultTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -1113,6 +1115,8 @@ void ODBCPostgreSQLTest::testDynamicAny()
|
||||
|
||||
void ODBCPostgreSQLTest::testMultipleResults()
|
||||
{
|
||||
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
|
||||
/*
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
@ -1124,6 +1128,7 @@ void ODBCPostgreSQLTest::testMultipleResults()
|
||||
|
||||
i += 2;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
// uncomment to use Mammoth ODBCng driver
|
||||
//#define POCO_ODBC_USE_MAMMOTH_NG
|
||||
#define POCO_ODBC_USE_MAMMOTH_NG
|
||||
|
||||
|
||||
class ODBCPostgreSQLTest: public CppUnit::TestCase
|
||||
|
@ -987,14 +987,8 @@ Deprecated types are not supported as output parameters. Use current large obje
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::testStoredCursorProcedure()
|
||||
void ODBCSQLServerTest::testCursorStoredProcedure()
|
||||
{
|
||||
/*TODO: Support for returning recordsets from MS SQL Server is currently limited.
|
||||
In order for it to work, nothing else but the recordset (not even output parameters)
|
||||
can be returned.
|
||||
To achieve full functionality, SQLMoreResults functionality probably must be incorporated
|
||||
into the framework.
|
||||
*/
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int k = 0; k < 8;)
|
||||
@ -1204,63 +1198,6 @@ void ODBCSQLServerTest::testStoredFunction()
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::testStoredCursorFunction()
|
||||
{
|
||||
/* TODO (see comments about errors below - probably needs SQLMoreResults to function properly)
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int k = 0; k < 8;)
|
||||
{
|
||||
_pSession->setFeature("autoBind", bindValues[k]);
|
||||
_pSession->setFeature("autoExtract", bindValues[k+1]);
|
||||
|
||||
recreatePersonTable();
|
||||
typedef Tuple<std::string, std::string, std::string, int> Person;
|
||||
std::vector<Person> people;
|
||||
people.push_back(Person("Simpson", "Homer", "Springfield", 42));
|
||||
people.push_back(Person("Simpson", "Bart", "Springfield", 12));
|
||||
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
|
||||
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
|
||||
|
||||
dropObject("PROCEDURE", "storedCursorFunction");
|
||||
*_pSession << "CREATE PROCEDURE storedCursorFunction(@ageLimit int) AS "
|
||||
"BEGIN "
|
||||
" SELECT * "
|
||||
" FROM Person "
|
||||
" WHERE Age < @ageLimit "
|
||||
" ORDER BY Age DESC; "
|
||||
" RETURN @ageLimit; "
|
||||
"END;"
|
||||
, now;
|
||||
|
||||
people.clear();
|
||||
int age = 13;
|
||||
int result = 0;
|
||||
|
||||
*_pSession << "{? = call storedCursorFunction(?)}", out(result), in(age), into(people), now;
|
||||
|
||||
//assert (result == age); //fails (result == 0)
|
||||
assert (2 == people.size());
|
||||
assert (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
|
||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
|
||||
|
||||
result = 0;
|
||||
Statement stmt = ((*_pSession << "{? = call storedCursorFunction(?)}", out(result), in(age), now));
|
||||
RecordSet rs(stmt);
|
||||
assert (rs["LastName"] == "Simpson");
|
||||
assert (rs["FirstName"] == "Bart");
|
||||
assert (rs["Address"] == "Springfield");
|
||||
assert (rs["Age"] == 12);
|
||||
|
||||
dropObject("TABLE", "Person");//fails ([Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt")
|
||||
dropObject("PROCEDURE", "storedCursorFunction");
|
||||
|
||||
k += 2;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::testRowIterator()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
@ -1638,11 +1575,10 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredCursorProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testCursorStoredProcedure);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureAny);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredCursorFunction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
||||
|
@ -120,11 +120,10 @@ public:
|
||||
void testTupleVector();
|
||||
|
||||
void testStoredProcedure();
|
||||
void testStoredCursorProcedure();
|
||||
void testCursorStoredProcedure();
|
||||
void testStoredProcedureAny();
|
||||
void testStoredProcedureDynamicAny();
|
||||
void testStoredFunction();
|
||||
void testStoredCursorFunction();
|
||||
|
||||
void testInternalExtraction();
|
||||
void testInternalStorageType();
|
||||
|
@ -56,12 +56,13 @@
|
||||
#include <iterator>
|
||||
|
||||
|
||||
#define print_odbc_error(r, h) \
|
||||
#define poco_odbc_check(r, h) \
|
||||
if (!SQL_SUCCEEDED(r)) \
|
||||
{ \
|
||||
StatementException se(h); \
|
||||
std::cout << se.toString() << std::endl; \
|
||||
}
|
||||
} \
|
||||
assert (SQL_SUCCEEDED(r));
|
||||
|
||||
|
||||
using namespace Poco::Data;
|
||||
@ -218,13 +219,13 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
|
||||
// Environment begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Connection begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
POCO_SQLCHAR connectOutput[512] = {0};
|
||||
SQLSMALLINT result;
|
||||
@ -236,14 +237,14 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
, sizeof(connectOutput)
|
||||
, &result
|
||||
, SQL_DRIVER_NOPROMPT);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// retrieve datetime type information for this DBMS
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetTypeInfo(hstmt, SQL_TIMESTAMP);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
SQLINTEGER dateTimeColSize = 0;
|
||||
SQLSMALLINT dateTimeDecDigits = 0;
|
||||
|
||||
@ -252,19 +253,19 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
if (SQL_SUCCEEDED(rc))
|
||||
{
|
||||
rc = SQLGetData(hstmt, 3, SQL_C_SLONG, &dateTimeColSize, sizeof(SQLINTEGER), 0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLGetData(hstmt, 14, SQL_C_SSHORT, &dateTimeDecDigits, sizeof(SQLSMALLINT), 0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
else if (SQL_NO_DATA == rc)
|
||||
std::cerr << "Warning: no data type info returned by driver." << std::endl;
|
||||
|
||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Statement begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
std::string sql = "DROP TABLE Test";
|
||||
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
@ -275,15 +276,15 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
sql = tableCreateString;
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLExecute(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
sql = "INSERT INTO Test VALUES (?,?,?,?,?,?)";
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
std::string str[3] = { "111", "222", "333" };
|
||||
int fourth = 4;
|
||||
@ -314,7 +315,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) str[0].c_str(),
|
||||
size,
|
||||
&li);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
size = (SQLINTEGER) str[1].size();
|
||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||
@ -330,7 +331,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) str[1].c_str(),
|
||||
size,
|
||||
&li);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
size = (SQLINTEGER) str[2].size();
|
||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||
@ -347,7 +348,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) str[2].data(),
|
||||
size,
|
||||
&li);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindParameter(hstmt,
|
||||
(SQLUSMALLINT) 4,
|
||||
@ -359,7 +360,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &fourth,
|
||||
0,
|
||||
0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindParameter(hstmt,
|
||||
(SQLUSMALLINT) 5,
|
||||
@ -371,7 +372,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &fifth,
|
||||
0,
|
||||
0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindParameter(hstmt,
|
||||
(SQLUSMALLINT) 6,
|
||||
@ -383,7 +384,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &sixth,
|
||||
0,
|
||||
0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
size = 0;
|
||||
if (SQLExecutor::PB_AT_EXEC == bindMode)
|
||||
@ -414,12 +415,12 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
++i;
|
||||
}while (SQL_NEED_DATA == (rc = SQLParamData(hstmt, &pParam)));
|
||||
}
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
sql = "SELECT * FROM Test";
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
char chr[3][5] = {{ 0 }};
|
||||
SQLLEN lengths[6] = { 0 };
|
||||
@ -435,7 +436,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) chr[0],
|
||||
(SQLINTEGER) 4,
|
||||
&lengths[0]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 2,
|
||||
@ -443,7 +444,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) chr[1],
|
||||
(SQLINTEGER) 4,
|
||||
&lengths[1]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 3,
|
||||
@ -451,7 +452,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) chr[2],
|
||||
(SQLINTEGER) 4,
|
||||
&lengths[2]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 4,
|
||||
@ -459,7 +460,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &fourth,
|
||||
(SQLINTEGER) 0,
|
||||
&lengths[3]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 5,
|
||||
@ -467,7 +468,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &fifth,
|
||||
(SQLINTEGER) 0,
|
||||
&lengths[4]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 6,
|
||||
@ -475,13 +476,13 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &sixth,
|
||||
(SQLINTEGER) 0,
|
||||
&lengths[5]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
rc = SQLExecute(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLFetch(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||
{
|
||||
@ -491,7 +492,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
chr[0],
|
||||
4,
|
||||
&lengths[0]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 2,
|
||||
@ -499,7 +500,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
chr[1],
|
||||
4,
|
||||
&lengths[1]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 3,
|
||||
@ -507,7 +508,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
chr[2],
|
||||
3,
|
||||
&lengths[2]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 4,
|
||||
@ -515,7 +516,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
&fourth,
|
||||
0,
|
||||
&lengths[3]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 5,
|
||||
@ -523,7 +524,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
&fifth,
|
||||
0,
|
||||
&lengths[4]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 6,
|
||||
@ -531,7 +532,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
&sixth,
|
||||
0,
|
||||
&lengths[5]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
assert (0 == strncmp("111", chr[0], 3));
|
||||
@ -550,25 +551,25 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
|
||||
}
|
||||
|
||||
rc = SQLCloseCursor(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
sql = "DROP TABLE Test";
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Connection end
|
||||
rc = SQLDisconnect(hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Environment end
|
||||
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
|
||||
@ -586,13 +587,13 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
|
||||
// Environment begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Connection begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
POCO_SQLCHAR connectOutput[512] = {0};
|
||||
SQLSMALLINT result;
|
||||
@ -604,11 +605,11 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
, sizeof(connectOutput)
|
||||
, &result
|
||||
, SQL_DRIVER_NOPROMPT);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Statement begin
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
std::string sql = "DROP TABLE Test";
|
||||
POCO_SQLCHAR* pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
@ -619,17 +620,17 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
sql = tableCreateString;
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLExecute(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// insert multiple rows
|
||||
pStr = (POCO_SQLCHAR*) insert.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) insert.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLExecute(hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
do
|
||||
{
|
||||
SQLINTEGER rowCount = 0;
|
||||
@ -638,10 +639,49 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
|
||||
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
||||
|
||||
// make sure all five rows made it in
|
||||
sql = "select count(*) from Test";
|
||||
int count = 0;
|
||||
SQLLEN length = 0;
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
poco_odbc_check (rc, hstmt);
|
||||
if (SQLExecutor::DE_BOUND == extractMode)
|
||||
{
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 1,
|
||||
SQL_C_SLONG,
|
||||
(SQLPOINTER) &count,
|
||||
(SQLINTEGER) 0,
|
||||
&length);
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
rc = SQLExecute(hstmt);
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLFetch(hstmt);
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||
{
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 1,
|
||||
SQL_C_SLONG,
|
||||
&count,
|
||||
0,
|
||||
&length);
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
assert (5 == count);
|
||||
|
||||
rc = SQLCloseCursor(hstmt);
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// select multiple rows
|
||||
pStr = (POCO_SQLCHAR*) select.c_str();
|
||||
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) select.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
char chr[5] = { 0 };
|
||||
SQLLEN lengths[3] = { 0 };
|
||||
@ -656,7 +696,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) chr,
|
||||
(SQLINTEGER) 4,
|
||||
&lengths[0]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 2,
|
||||
@ -664,7 +704,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &second,
|
||||
(SQLINTEGER) 0,
|
||||
&lengths[1]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLBindCol(hstmt,
|
||||
(SQLUSMALLINT) 3,
|
||||
@ -672,22 +712,21 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
(SQLPOINTER) &third,
|
||||
(SQLINTEGER) 0,
|
||||
&lengths[2]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
rc = SQLExecute(hstmt);
|
||||
print_odbc_error (rc, hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
char one = 0x31;
|
||||
int two = 2;
|
||||
float three = 3.5;
|
||||
count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
rc = SQLFetch(hstmt);
|
||||
print_odbc_error (rc, hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
if (SQLExecutor::DE_MANUAL == extractMode)
|
||||
{
|
||||
@ -697,7 +736,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
chr,
|
||||
4,
|
||||
&lengths[0]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 2,
|
||||
@ -705,7 +744,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
&second,
|
||||
0,
|
||||
&lengths[1]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLGetData(hstmt,
|
||||
(SQLUSMALLINT) 3,
|
||||
@ -713,7 +752,7 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
&third,
|
||||
0,
|
||||
&lengths[2]);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
assert (one++ == chr[0]);
|
||||
@ -721,25 +760,28 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
|
||||
assert (three == third);
|
||||
three += 1.0;
|
||||
|
||||
++count;
|
||||
} while (SQL_NO_DATA != SQLMoreResults(hstmt));
|
||||
|
||||
assert (5 == count);
|
||||
|
||||
sql = "DROP TABLE Test";
|
||||
pStr = (POCO_SQLCHAR*) sql.c_str();
|
||||
rc = SQLExecDirect(hstmt, pStr, (SQLINTEGER) sql.length());
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Connection end
|
||||
rc = SQLDisconnect(hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
|
||||
// Environment end
|
||||
rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||
assert (SQL_SUCCEEDED(rc));
|
||||
poco_odbc_check (rc, hstmt);
|
||||
}
|
||||
|
||||
|
||||
@ -2569,7 +2611,7 @@ void SQLExecutor::dynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::multipleResults()
|
||||
void SQLExecutor::multipleResults(const std::string& sql)
|
||||
{
|
||||
typedef Tuple<std::string, std::string, std::string, int> Person;
|
||||
std::vector<Person> people;
|
||||
@ -2578,16 +2620,22 @@ void SQLExecutor::multipleResults()
|
||||
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
|
||||
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
|
||||
|
||||
Person Homer, Lisa, Bart;
|
||||
Person pHomer, pLisa;
|
||||
int aHomer(42), aLisa(10), aBart(0);
|
||||
|
||||
*_pSession << "SELECT * FROM Person WHERE FirstName = 'Homer'; "
|
||||
"SELECT * FROM Person WHERE FirstName = 'Bart'; "
|
||||
"SELECT * FROM Person WHERE FirstName = 'Lisa'; "
|
||||
, into(Homer, 0), into(Bart, 1), into(Lisa, 2)
|
||||
try {
|
||||
*_pSession << sql
|
||||
, into(pHomer), use(aHomer)
|
||||
, into(aBart, 1)
|
||||
, into(pLisa, 2), use(aLisa)
|
||||
, now;
|
||||
} catch (StatementException& ex)
|
||||
{
|
||||
std::cout << ex.toString() << std::endl;
|
||||
}
|
||||
|
||||
assert (Person("Simpson", "Homer", "Springfield", 42) == Homer);
|
||||
assert (Person("Simpson", "Bart", "Springfield", 12) == Bart);
|
||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == Lisa);
|
||||
assert (Person("Simpson", "Homer", "Springfield", 42) == pHomer);
|
||||
assert (12 == aBart);
|
||||
assert (Person("Simpson", "Lisa", "Springfield", 10) == pLisa);
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,10 @@ public:
|
||||
void any();
|
||||
void dynamicAny();
|
||||
|
||||
void multipleResults();
|
||||
void multipleResults(const std::string& sql =
|
||||
"SELECT * FROM Person WHERE Age = ?; "
|
||||
"SELECT Age FROM Person WHERE FirstName = 'Bart'; "
|
||||
"SELECT * FROM Person WHERE Age = ?; ");
|
||||
|
||||
private:
|
||||
static const std::string MULTI_INSERT;
|
||||
|
@ -600,7 +600,7 @@ Binding<T>* in(const T& t, const std::string& name = "")
|
||||
|
||||
|
||||
template <typename T>
|
||||
Binding<T>* out(const T& t, const std::string& name = "")
|
||||
Binding<T>* out(T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_OUT);
|
||||
@ -610,7 +610,7 @@ Binding<T>* out(const T& t, const std::string& name = "")
|
||||
|
||||
|
||||
template <typename T>
|
||||
Binding<T>* io(const T& t, const std::string& name = "")
|
||||
Binding<T>* io(T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN_OUT);
|
||||
|
@ -346,7 +346,6 @@ Poco::UInt32 StatementImpl::activateNextDataSet()
|
||||
void StatementImpl::addExtract(AbstractExtraction* pExtraction)
|
||||
{
|
||||
poco_check_ptr (pExtraction);
|
||||
|
||||
Poco::UInt32 pos = pExtraction->position();
|
||||
if (pos >= _extractors.size())
|
||||
_extractors.resize(pos + 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user