3939#include " Poco/Data/ODBC/Utility.h"
4040#include " Poco/Data/ODBC/ODBCException.h"
4141#include " Poco/Data/AbstractPrepare.h"
42+ #include < limits>
4243#include < sql.h>
44+ #undef max
4345
4446
4547namespace Poco {
@@ -88,18 +90,10 @@ void ODBCStatementImpl::compileImpl()
8890 _stepCalled = false ;
8991 _nextResponse = 0 ;
9092
91- std::string statement (toString ());
92- if (statement.empty ())
93- throw ODBCException (" Empty statements are illegal" );
93+ if (_preparations.size ())
94+ PreparationVec ().swap (_preparations);
9495
95- Preparation::DataExtraction ext = session ().getFeature (" autoExtract" ) ?
96- Preparation::DE_BOUND : Preparation::DE_MANUAL ;
97-
98- std::size_t maxFieldSize = AnyCast<std::size_t >(session ().getProperty (" maxFieldSize" ));
99- _pPreparation = new Preparation (_stmt,
100- statement,
101- maxFieldSize,
102- ext);
96+ addPreparation ();
10397
10498 Binder::ParameterBinding bind = session ().getFeature (" autoBind" ) ?
10599 Binder::PB_IMMEDIATE : Binder::PB_AT_EXEC ;
@@ -112,7 +106,6 @@ void ODBCStatementImpl::compileImpl()
112106 }catch (NotSupportedException&) { }
113107
114108 _pBinder = new Binder (_stmt, bind, pDT);
115- _pExtractor = new Extractor (_stmt, *_pPreparation);
116109
117110 // This is a hack to conform to some ODBC drivers behavior (e.g. MS SQLServer) with
118111 // stored procedure calls: driver refuses to report the number of columns, unless all
@@ -137,22 +130,46 @@ void ODBCStatementImpl::makeInternalExtractors()
137130}
138131
139132
133+ void ODBCStatementImpl::addPreparation ()
134+ {
135+ if (0 == _preparations.size ())
136+ {
137+ std::string statement (toString ());
138+ if (statement.empty ())
139+ throw ODBCException (" Empty statements are illegal" );
140+
141+ Preparation::DataExtraction ext = session ().getFeature (" autoExtract" ) ?
142+ Preparation::DE_BOUND : Preparation::DE_MANUAL ;
143+
144+ std::size_t maxFieldSize = AnyCast<std::size_t >(session ().getProperty (" maxFieldSize" ));
145+
146+ _preparations.push_back (new Preparation (_stmt, statement, maxFieldSize, ext));
147+ }
148+ else
149+ _preparations.push_back (new Preparation (*_preparations[0 ]));
150+
151+ _extractors.push_back (new Extractor (_stmt, *_preparations.back ()));
152+ }
153+
154+
140155void ODBCStatementImpl::doPrepare ()
141156{
142- if (!_prepared && session ().getFeature (" autoExtract" ) && hasData ())
157+ if (session ().getFeature (" autoExtract" ) && hasData ())
143158 {
144- poco_check_ptr (_pPreparation);
159+ Poco::UInt32 curDataSet = currentDataSet ();
160+ poco_check_ptr (_preparations[curDataSet]);
145161
146162 Extractions& extracts = extractions ();
147163 Extractions::iterator it = extracts.begin ();
148164 Extractions::iterator itEnd = extracts.end ();
149165 for (std::size_t pos = 0 ; it != itEnd; ++it)
150166 {
151- AbstractPrepare* pAP = (*it)->createPrepareObject (_pPreparation , pos);
167+ AbstractPrepare* pAP = (*it)->createPrepareObject (_preparations[curDataSet] , pos);
152168 pAP->prepare ();
153169 pos += (*it)->numOfColumnsHandled ();
154170 delete pAP;
155171 }
172+
156173 _prepared = true ;
157174 }
158175}
@@ -263,14 +280,32 @@ bool ODBCStatementImpl::hasNext()
263280 if (_stepCalled)
264281 return _stepCalled = nextRowReady ();
265282
266- _stepCalled = true ;
267- _pExtractor->reset ();
268- _nextResponse = SQLFetch (_stmt);
283+ makeStep ();
269284
270285 if (!nextRowReady ())
271- return false ;
272- else
273- if (Utility::isError (_nextResponse))
286+ {
287+ try
288+ {
289+ activateNextDataSet ();
290+ } catch (InvalidAccessException&)
291+ {
292+ return false ;
293+ }
294+
295+ addPreparation ();
296+ doPrepare ();
297+ fixupExtraction ();
298+
299+ try
300+ {
301+ checkError (SQLMoreResults (_stmt));
302+ } catch (NoDataException&)
303+ {
304+ return false ;
305+ }
306+ makeStep ();
307+ }
308+ else if (Utility::isError (_nextResponse))
274309 checkError (_nextResponse, " SQLFetch()" );
275310
276311 return true ;
@@ -280,12 +315,18 @@ bool ODBCStatementImpl::hasNext()
280315}
281316
282317
318+ void ODBCStatementImpl::makeStep ()
319+ {
320+ _extractors[currentDataSet ()]->reset ();
321+ _nextResponse = SQLFetch (_stmt);
322+ _stepCalled = true ;
323+ }
324+
325+
283326void ODBCStatementImpl::next ()
284327{
285328 if (nextRowReady ())
286329 {
287- poco_assert (columnsExtracted () == _pPreparation->columns ());
288-
289330 Extractions& extracts = extractions ();
290331 Extractions::iterator it = extracts.begin ();
291332 Extractions::iterator itEnd = extracts.end ();
0 commit comments