title: SQL Server and OLE DB Consumer: pointer to IUnknown interface of a Rowset Object
body: <p>How can I iterate over a pointer to IUnknown interface of a Rowset Object using the select command like the code below?
  What I need to do is to get all the lines (using a while loop) returned by the command:</p>
  
  <p>FAIL_IF( ExecuteSQL( spUnkCommand, "select * from sasuser.newtable", spUnkRowset ) );</p>
  
  <p>Please see below the complete code from <a href="http://support.sas.com/documentation/tools/oledb/rr_sqliomshare.htm" rel="nofollow">http://support.sas.com/documentation/tools/oledb/rr_sqliomshare.htm</a></p>
  
  <pre><code>#include "stdafx.h"
  #include "atlbase.h"
  #include "comdef.h"
  #include "comutil.h"
  #include "oledb.h"
  #include "atldbcli.h"
  
  #include &lt;iostream&gt;
  #include &lt;iomanip&gt;
  using std::cout;
  using std::hex;
  using std::setw;
  using std::setfill;
  using std::right;
  using std::endl;
  
  #define FAIL_IF( hr ) issue_if_failed( __FILE__, __LINE__, hr )
  inline void issue_if_failed( char* file, ULONG line, HRESULT hr )
  {
      /* This method throws an error if hr is a failure. */
      if( FAILED( hr ) )
      {
          ATLTRACE( "%s(%d): Failure 0x%X\n", (char*)file, line, hr );
          _com_issue_error( hr );
      }
  }
  
  HRESULT InstantiateProvider( CComPtr&lt;IUnknown&gt;&amp; spUnkDataSrc )
  {
      /* spUnkDataSrc contains a NULL IUnknown pointer.                   */
      /* This method instantiates the IOM Provider Data Source object and */
      /* stores a pointer to it's IUnknown interface in spUnkDataSrc.     */
      CLSID clsid;
  
      FAIL_IF( CLSIDFromProgID( L"SQLOLEDB.1", &amp;clsid ) );
      FAIL_IF( CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&amp;spUnkDataSrc ) );
  
      return S_OK;
  }
  
  HRESULT InitializeProvider( CComPtr&lt;IUnknown&gt;&amp; spUnkDataSrc )
  {
      /* spUnkDataSrc contains a IUnknown pointer to an uninitialized IOM Data Source Object. */
      /* This method initializes the IOM Provider specifically.  Initializing the SAS/SHARE  */
      /* Provider requires different properties as described in Opening an ADO Connection Object. */
      CComQIPtr&lt;IDBInitialize&gt; spInit = spUnkDataSrc;
      CComQIPtr&lt;IDBProperties&gt; spProp = spUnkDataSrc;
      if( spInit == NULL || spProp == NULL )
          return E_FAIL;
  
      CDBPropSet Props( DBPROPSET_DBINIT );
      Props.AddProperty( DBPROP_INIT_DATASOURCE, (WCHAR*)L"XXXXXXXXXXXX" ); // Host
      Props.AddProperty( DBPROP_INIT_CATALOG, L"DBDBDBDBDB" ); // Database
      Props.AddProperty( DBPROP_AUTH_USERID, L"sa" ); // user
      Props.AddProperty( DBPROP_AUTH_PASSWORD, L"PWDPWDPWDPWD"); // password
      FAIL_IF( spProp-&gt;SetProperties( 1, &amp;Props ) );
  
      FAIL_IF( spInit-&gt;Initialize() );
  
      return S_OK;
  }
  
  HRESULT CreateSession( CComPtr&lt;IUnknown&gt;&amp; spUnkDataSrc, CComPtr&lt;IUnknown&gt;&amp; spUnkSession )
  {
      /* spUnkDataSrc contains a pointer to the IUnknown interface of an initialized Data Source Object               */
      /* spUnkSession is where a pointer to the IUnknown interface of the newly created Session Object will be stored */
      HRESULT hr = E_FAIL;
      CComQIPtr&lt;IDBCreateSession&gt; spCreateSession = spUnkDataSrc;
      if( spCreateSession == NULL )
          cout &lt;&lt; "ERROR: IDBCreateSession not found" &lt;&lt; endl;
      else
      {
          hr = spCreateSession-&gt;CreateSession( NULL, IID_IUnknown, &amp;spUnkSession.p );
          FAIL_IF( hr );
      }
      return hr;
  
  }
  
  HRESULT CreateCommand( CComPtr&lt;IUnknown&gt;&amp; spUnkSession, CComPtr&lt;IUnknown&gt;&amp; spUnkCommand )
  {
      /* spUnkSession contains a pointer to the IUnknown interface of an open Session Object                          */
      /* spUnkCommand is where a pointer to the IUnknown interface of the newly created Command Object will be stored */
      HRESULT hr = E_FAIL;
      CComQIPtr&lt;IDBCreateCommand&gt; spCreateCommand = spUnkSession;
      if( spCreateCommand == NULL )
          cout &lt;&lt; "ERROR: IDBCreateCommand not found" &lt;&lt; endl;
      {
          hr = spCreateCommand-&gt;CreateCommand( NULL, IID_IUnknown, &amp;spUnkCommand.p );
          FAIL_IF( hr );
      }
      return hr;
  }
  
  HRESULT ExecuteSQL( CComPtr&lt;IUnknown&gt;&amp; spUnkCommand, bstr_t bstrSQL, CComPtr&lt;IUnknown&gt;&amp; spUnkRowset )
  {
      /* spUnkCommand contains a pointer to the IUnknown interface of an open command           */
      /* spUnkRowset is where the IUknown pointer to the created rowset (if any) will be stored */
      HRESULT hr = E_FAIL;
      CComQIPtr&lt;ICommandText&gt; spCommandText = spUnkCommand;
      if( spCommandText == NULL )
          cout &lt;&lt; "ERROR: ICommandText not found" &lt;&lt; endl;
      else
      {
          FAIL_IF( spCommandText-&gt;SetCommandText( DBGUID_DBSQL, bstrSQL ) );
          hr = spCommandText-&gt;Execute( NULL, IID_IUnknown, NULL, NULL, &amp;spUnkRowset.p );
          FAIL_IF( hr );
      }
      return hr;
  }
  
  int main(int argc, char* argv[])
  {
      CoInitialize(NULL);
  
      try
      {
          HRESULT hr = E_FAIL;
          CComPtr&lt;IUnknown&gt; spUnkDataSrc = NULL; /* pointer to IUnknown interface of a Data Source Object */
          CComPtr&lt;IUnknown&gt; spUnkSession = NULL; /* pointer to IUnknown interface of a Session Object */
          CComPtr&lt;IUnknown&gt; spUnkCommand = NULL; /* pointer to IUnknown interface of a Command Object */
          CComPtr&lt;IUnknown&gt; spUnkRowset = NULL;  /* pointer to IUnknown interface of a Rowset Object */
          FAIL_IF( InstantiateProvider( spUnkDataSrc ) ); /* creates an instance of the IOM Provider Data Source */
          FAIL_IF( InitializeProvider( spUnkDataSrc ) );  /* initializes the Data Source object to connect to the local COM IOM server */
          FAIL_IF( CreateSession( spUnkDataSrc, spUnkSession ) ); /* creates an instance of a Session Object */
          FAIL_IF( CreateCommand( spUnkSession, spUnkCommand ) ); /* creates an instance of a Command Object */
  
          FAIL_IF( ExecuteSQL( spUnkCommand, "select * from table_name", spUnkRowset ) );
  
          /* do something with spUnkRowset */
          /* ??????? */
  
  
  
      }
      catch( _com_error&amp; e )
      {
          cout &lt;&lt; "ERROR: 0x" &lt;&lt; hex &lt;&lt; setw(8) &lt;&lt; setfill('0') &lt;&lt; right &lt;&lt; e.Error() &lt;&lt; endl;
      }
  
      CoUninitialize();
      return 0;
  }
  </code></pre>