# SQL Query Result Processing in C++

> The QueryResult class provides a convenient way to process SQL result set rows. The `records()` method returns a Cursor object that provides method `hasNext()` to iterate over the result set rows and a number of methods for extracting the data or column information from these rows. For example the following code snippet demonstrates how to extract and print out the values from the result set of query "select * from Person" (see here for the definition of database class `Person`):

>         void show_results(McoSqlEngine& engine)
>         {
>             QueryResult result(engine.executeQuery("select * from Person"));
>             Cursor * cursor = result->records();

>             while (cursor->hasNext())
>             {
>                 Record * rec = cursor->next();

>                 // Extract the _Person record to the corresponding struct
>                 _Person p;
>                 result->extract(rec, &p, sizeof(p));
>                 printf("\tName=%s, Ordinal=%u\n", p.name, p.ordinal );
>             }
>         }

> Note that the `struct` `_Person` is:

>         // Define the structure correponding to database table Person
>         struct _Person
>         {
>             char const* name;
>             uint4       ordinal;
>         };

> ## QueryResult usage

> The main purpose of the C++ QueryResult is to control the scope of the query and automatically release all allocated resources if the query is terminated abnormally. If the scope of the query (the lifetime of the QueryResult object instance) is incorrect it will lead to a runtime error. This can happen when the instance is used beyond the transaction it has been created in or still exists at the time the database instance is closed. The following code snippet demonstrates how this kind of incorrect usage may occur:

>         main (void)
>         {
>             McoSqlEngine engine;
>             engine.open( ... );

>             ...

>             QueryResult result(engine.executeQuery("select * from aRecord"));
>             Cursor* cursor = result->records();
>             while (cursor->hasNext()) {
>                 ...
>             } /* end of while loop */
>             engine.close(); /* database instance is destroyed here */
>             return 0;

>             /* object of class QueryResult represented by local variable 'result' will be deleted
>             here. Since the database no longer exists, the QueryResult destructor crashes the
>             application */
>         }

> Because the transaction context that created the object is kept within the object, if the transaction is no longer valid, any operation over its handle leads to an error. In the code above, the QueryResult destructor is called as the object `result` goes out of scope. But the transaction handle in result is no longer valid because the database has been closed. So the attempt to close the transaction causes the application to crash!

> To avoid this, any instance of the QueryResult class must be deleted as soon as it is no longer required. This can be done by explicitly calling the `delete` operator on the object if it was created by `new`, or by using enclosing braces if the object is instantiated as a local variable.