c++ going from Database record set into an array

have successfully retrieved the data fro the database now i need to gethis into and multi dim array so that i can operate on the information,
half way down the page is were it needs to be inserted markjed with
// *****************************************************************
// AT THIS POSITION I NEED TO GET HIS DATA INTO AN ARRAY SO THAT I CAN MANIPUPLATE THE
//  DATS AS MY NEEDS ARE DETERMINED
//*******************************************************************
i am reading up on how to do strings ext meanwhile hope you can help
thanks for reading



// This is the main project file for VC++ application project
// generated using an Application Wizard.
//
//    this works well in this confuration
//
 #include      "StdAfx.h"
//#include "stdafx.h"
#include  <atldbcli.h>
//#include  <atldbsch.h>
//#include <ostream>
#include <iostream>
#include <string>
//#include <wtypes.h>


//#using <mscorlib.dll>


//using namespace System;
using namespace std;

int _tmain()
{
    // TODO: Please replace the sample code below with your own.
    HRESULT hr = 0;
    std::string str;
    int i=0, ret=0;
   char arrayd[1][4] ;
   for(int row = 0;row<5;row++)
   {
            for(int col = 0;col<5;col++)
            {
                        cout<<arrayd[row][col]<<  "1 ";
            }
   }
 //  arrayd[4] = "kkjkjkj";
//      char array_of_strings[1][1];
//       array_of_strings[1][1] = strcpy("jjhjhjhj");
//      string DBData[5][6];
//      DBData[0][1] = "sdsdsdsd";
  //  std::string query;
      string DAM;
      //Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;
      //   Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\c++ tree view\\new files\\DB\\TreeView.mdb;User Id=admin;Password=;
      LPCOLESTR lpcOleConnect = L"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\c++ tree view\\new files\\DB\\TreeView.mdb;User Id=admin;;Password=;";

                  // To initialize the connection to a database using an OLE DB provider,
            // two ATL classes are needed: CDataSource and CSession.
            CDataSource dbDataSource;
            CSession dbSession;

            // Uses ATL's string conversion macros to convert between character encodings.
            USES_CONVERSION;

            // Open the connection and initialize the data source specified by the passed
            // initialization string.
            hr = dbDataSource.OpenFromInitializationString(lpcOleConnect);
            if (FAILED(hr))
            {
                  cout<<DAM<<": Unable to connect to data source "<<OLE2T(lpcOleConnect)<<endl;
            }
            else
            {
                  hr = dbSession.Open(dbDataSource);
                  if (FAILED(hr))
                  {
                        cout<<DAM<<": Couldn't create session on data source "<<OLE2T(lpcOleConnect)<<endl;
                  }
                  else
                  {
                        CComVariant var;
                        hr = dbDataSource.GetProperty(DBPROPSET_DATASOURCEINFO, DBPROP_DATASOURCENAME, &var);
                        if (FAILED(hr) || (var.vt == VT_EMPTY))
                        {
                              cout<<DAM<<": No Data Source Name Specified."<<endl;
                        }
                        else
                        {
                              cout<<DAM<<": Successfully connected to database. Data source name:\n  "
                                    <<COLE2T(var.bstrVal)<<endl;
x
                              // Prepare SQL query.
                              
                  //            LPCOLESTR query = L"SELECT ParentTable.ParentId, ParentTable.ParentName,ParentTable.a,ParentTable.b,ParentTable.c FROM ParentTable;";


                   //      LPCOLESTR query = L"SELECT ParentTable.ParentId, ParentTable.ParentName, ChildTable.ChildId, ChildTable.ChildName FROM ParentTable INNER JOIN ChildTable ON ParentTable.ParentId = ChildTable.ParentId;";
                              
                              LPCOLESTR query = L"SELECT * from bothtaables;";
                              
                              cout<<DAM<<": SQL query:\n  "<<OLE2T(query)<<endl;

                              // Excecute the query and create a record set.
                              CCommand<CDynamicStringAccessor> cmd;
                              hr = cmd.Open(dbSession, query);
                              DBORDINAL colCount = cmd.GetColumnCount();
                              if (SUCCEEDED(hr) && 0 < colCount)
                              {
                                    cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
                                    DBORDINAL cColumns;
                                    DBCOLUMNINFO* rgInfo = NULL;
                                    OLECHAR* pStringsBuffer = NULL;
                                    cmd.GetColumnInfo(&cColumns, &rgInfo, &pStringsBuffer);
                                    for (int col=0; col < (int)colCount; col++)
                                    {
                                          cout<<" | "<<OLE2T(rgInfo[col].pwszName);
                           
                                    }
                                    cout<<endl;

                                    cout<<DAM<<": Fetch the actual data: "<<endl;
                                    int rowCount = 0;
                                    CRowset<CDynamicStringAccessor>* pRS = (CRowset<CDynamicStringAccessor>*)&cmd;
                                    // Loop through the rows in the result set.
                                    while (pRS->MoveNext() == S_OK)
                                    {
                                          for (int col=1; col <= (int)colCount; col++)
                                          {
                                                CHAR* szValue = cmd.GetString(col);

// *****************************************************************
// AT THIS POSITION I NEED TO GET HIS DATA INTO AN ARRAY SO THAT I CAN MANIPUPLATE THE
//  DATS AS MY NEEDS ARE DETERMINED
//*******************************************************************

                                                cout<<" | "<<szValue;

                              //            DBData[0][colCount] = *szValue ;

                                          }
                                          cout<<endl;
                                          rowCount++;
                                    }
                                    cout<<DAM<<": Total Row Count: "<<rowCount<<endl;
                              }                  
                              else
                              {
                              cout<<DAM<<": Error: Number of fields in the result set is 0."<<endl;
                              }
                        }  
                  }
            }

            dbDataSource.Close();
            dbSession.Close();
            cout<<DAM<<": Cleanup. Done."<<endl;

      return 0;
}
sydneyguyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Karrtik IyerSoftware ArchitectCommented:
Here is how I suggest we can do it with a two dimensional array which you trying to do. I have prefixed inline comments for each line I added with //Karrtik.
Steps involve
1. Getting the number of rows (record count) from open command
2. Creating a two dimensional string array
3. Allocating memory for the number of rows
4. For each row allocating memory for each column
5. Assign the value from DB to the two dimensional array
6. Print the data from two dimensional array
7. Delete the array when not needed
  cout<<DAM<<": Successfully connected to database. Data source name:\n  "
                                    <<COLE2T(var.bstrVal)<<endl;
                              // Prepare SQL query.
                              
                  //            LPCOLESTR query = L"SELECT ParentTable.ParentId, ParentTable.ParentName,ParentTable.a,ParentTable.b,ParentTable.c FROM ParentTable;";


                   //      LPCOLESTR query = L"SELECT ParentTable.ParentId, ParentTable.ParentName, ChildTable.ChildId, ChildTable.ChildName FROM ParentTable INNER JOIN ChildTable ON ParentTable.ParentId = ChildTable.ParentId;";
                              
                              LPCOLESTR query = L"SELECT * from bothtaables;";
                              
                              cout<<DAM<<": SQL query:\n  "<<OLE2T(query)<<endl;

                              // Excecute the query and create a record set.
                              CCommand<CDynamicStringAccessor> cmd;
long lrowcount = 0;//Karrtik: Create a variable to store row count
                              hr = cmd.Open(dbSession, query,null,&lrowcount);//Karrtik: Pass the 4th parameter of open function to get the row count
                              DBORDINAL colCount = cmd.GetColumnCount();
//Karrtik: Create a two dimensional string array to store the retrieved values
std::string** records = new std::string*[lrowcount];//Karrtik:Allocate memory to store the number of records
                              if (SUCCEEDED(hr) && 0 < colCount)
                              {
                                    cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
                                    DBORDINAL cColumns;
                                    DBCOLUMNINFO* rgInfo = NULL;
                                    OLECHAR* pStringsBuffer = NULL;
                                    cmd.GetColumnInfo(&cColumns, &rgInfo, &pStringsBuffer);
                                    for (int col=0; col < (int)colCount; col++)
                                    {
                                          cout<<" | "<<OLE2T(rgInfo[col].pwszName);
                           
                                    }
                                    cout<<endl;

                                    cout<<DAM<<": Fetch the actual data: "<<endl;
                                    int rowCount = 0;
long lrowindex =0;//Karrtik:Variable to store the current row index
                                    CRowset<CDynamicStringAccessor>* pRS = (CRowset<CDynamicStringAccessor>*)&cmd;
                                    // Loop through the rows in the result set.
                                    while (pRS->MoveNext() == S_OK)
                                    {
records[lrowindex]  = new string[(int)colCount];//Karrtik:Allocate memory for a array of string for each column for the i th row, this contains each column value for each row                                       
for (int col=1; col <= (int)colCount; col++)
                                          {
                                                CHAR* szValue = cmd.GetString(col);
records[lrowindex][col-1] =szValue ;//Karrtik: construct string for each col value 
// *****************************************************************
// AT THIS POSITION I NEED TO GET HIS DATA INTO AN ARRAY SO THAT I CAN MANIPUPLATE THE
//  DATS AS MY NEEDS ARE DETERMINED
//*******************************************************************

                                                cout<<" | "<<szValue;

                              //            DBData[0][colCount] = *szValue ;

                                          }
                                          cout<<endl;
                                          rowCount++;
++lrowindex ;//Karrtik: Increment the row index
                                    }
                                    cout<<DAM<<": Total Row Count: "<<rowCount<<endl;

Open in new window


To print all the records you can use code which shall look something like below:
for(long lrindex =0;lrindex < lrowcout;++lrindex){//Iterate number of rows
for(int colindex = 0; i < colCount; ++colindex) {//For each row iterate the columns
cout << records[lrindex][colindex].c_str() <<endl;//Print each col value for each row
}
}

Open in new window


Don't for forget to delete the two dimensional array when not needed to avoid memory leaks. It would be something like below.
for(int i = 0; i < colCount; ++i) {
    delete [] records[i];//Karrtik:Delete the column array for each row
}
delete [] records;//Karrtik:Delete all the rows

Open in new window

Karrtik IyerSoftware ArchitectCommented:
There are two other ways, that I can think of, are better than creating a two dimensional array. I shall explain both of them briefly below. In case you are interested in knowing any of them further let me know I shall explain further. Basically these methods avoid with developer having to allocate memory and releasing memory when not needed. Also one of these methods provides a more object oriented way of working with data from tables. And hence they are also easy to pass around to other functions and classes in your code.

Method 1>
a> Create a map to store each record, This map contains, colname/colindex as the key and column value as string in the map as value.
std::map<int, string> eachrecord; //Col index as the key
or
std::map<string, string> //column name as the string
b> Create a vector of the above map that represents all the records
Say typedef std::map<int, string> IndexBasedRecord;
typedef std::vector<IndexBasedRecord> Records;

c> Before the rows while loop create object of records like below
Records listofrecords;
while (pRS->MoveNext() == S_OK){
d> Inside while loop for each record create a object of map like below.
while (pRS->MoveNext() == S_OK){
IndexBasedRecord eachrecord;
e> Inside for loop for columns, insert values into map:
for (int col=1; col <= (int)colCount; col++)
                                          {
eachrecord.insert(std::pair<int, string>(col-1,szValue ));
f> After the column for loop, insert the map into the vector
listofrecords.push_back(eachrecord);
You can read more about maps and arrays using below tutorials.
1> Maps: http://www.cprogramming.com/tutorial/stl/stlmap.html
2> Vectors: http://www.cprogramming.com/tutorial/stl/vector.html

Method 2>
a> Create a class/structure that represents one record. say the data is related to Employee, then create a class called CEmployee with necessary fields. Basically create a object oriented interface (entity) for representing your db information.
b> Create a vector of CEmployee.
std::vector<CEmployee> listofemployees;//This could be even std::vector<CEmployee*>
c> Create a new CEmployee object for each row from the DB, which shall be in the below loop,
 while (pRS->MoveNext() == S_OK){
CEmployee objEmployee;//This can be even stored as pointer inside vector
d> Inside the column loop  :
 set the properties/values for each attribute of employee retrieved from DB. Which shall be in the column loop.
for (int col=1; col <= (int)colCount; col++)
                                          {
e> Before moving to the next item in the records, after the column loop, add the employee object to the vector of employees created.
listofemployees.push_back(objEmployee);
sarabandeCommented:
you may use a std::vector<std::vector<std::string> > to store the strings of the table in a 2d array.

std::vector<std::vector<std::string> > alltable;

....
   // Loop through the rows in the result set.
   int row = 0;
   while (pRS->MoveNext() == S_OK)
   {
         // add  a new row with colCount columns to alltable
         alltable.push_back(std::vector<std::string>(colCount));
         // get reference of last last row from alltable 
         std::vector<std::string> & rowarr = alltable.back();
         for (int col=0; col < (int)colCount; col++)
         {
                // note, since rowarr is a reference to the row in the array, 
                // the values actually are stored in the current row of alltable
                rowarr[col] = cmd.GetString(col+1);
                std::cout<<" | "<< alltable[row][col];
         }
         row++;
    }

Open in new window


Sara

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sydneyguyAuthor Commented:
thanks for all your help will revisit this area in a week when i come to stream lining this area again thanks for your help
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.