Un ejemplo de C++ de persistencia XML de conjunto de registros de ADO

En este artículo se describe cómo conservar o cargar un objeto Recordset de ADO en un archivo XML externo, un objeto ADO IStream y un objeto XML DOM.

Versión original del producto: Conjunto de registros de ADO
Número de KB original: 262450

Resumen

Con ADO 2.5 y versiones posteriores, los objetos Recordset se pueden conservar en cualquier objeto que implemente la IStream interfaz. En el código de ejemplo de este artículo se muestra cómo conservar o cargar un objeto Recordset de ADO en un archivo XML externo, un objeto ADO IStream y un objeto XML DOM.

Más información

  1. En el ejemplo se usa la tabla authors en la base de datos pubs de SQL Server Database.

  2. Modifique el cadena de conexión para proporcionar el nombre de origen de datos y las credenciales de usuario correctos.

  3. Dado que hay dos #import dll, para simplificar la programación, cambio el nombre del espacio de nombres ADO(ADODB)como MSXML y uso MSXML para las interfaces definidas en ambos archivos DLL. Como alternativa, siempre puede prefijar la interfaz con el espacio de nombres adecuado sin hacerlo.

Nota:

Debe cambiar User ID=<username> y Password=<strong password> a los valores correctos antes de ejecutar este código. Asegúrese de que User ID tiene los permisos adecuados para realizar esta operación en la base de datos.

// 1. ADO Recordset <-> external xml file
// 2. ADO Recordset <-> ADO IStream Object
// 3. ADO Recordset <-> DOM Document

#import "C:\Program files\Common Files\System\Ado\msado15.dll" rename_namespace("MSXML") rename("EOF", "ADOEOF")

#import "c:\winnt\system32\msxml.dll"
using namespace MSXML;

#include "stdio.h"
#include "io.h"
void dump_error(_com_error &e); //exception handling

void main()
{
    HRESULT hr;
    CoInitialize(NULL);

    try
    {
            //open the connection, get the reocrdset ready
            _ConnectionPtr pConn;
            _RecordsetPtr pRs;

            hr = pConn.CreateInstance(__uuidof(Connection));
            hr = pRs.CreateInstance(__uuidof(Recordset));

            pConn->CursorLocation = adUseClient;
            _bstr_t strConn("Provider=sqloledb;Data Source=juliaj01;Initial Catalog=pubs;User Id=<username>;Password=<strong password>;");
            hr = pConn->Open(strConn, "<username>", "<strong password>", adConnectUnspecified);
            hr = pRs->Open("SELECT * from authors", pConn.GetInterfacePtr(), adOpenForwardOnly, adLockReadOnly, adCmdText);

            //preparation to save RS as xml file,
            struct _finddata_t xml_file;
            long hFile;
            if( (hFile = _findfirst("authors.xml", &xml_file ))!= -1L)
            {
                DeleteFile("authors.xml"); //if the file exists, delete it
            }

            // 1. Persist it to an external xml file by calling Save with file name and adPersistXML
            hr = pRs->Save("authors.xml", adPersistXML);

            // 2. Persist it to ADO IStream Object
            _StreamPtrpStream ; //declare one first
            pStream.CreateInstance(__uuidof(Stream)); //create it after
            hr = pRs->Save(pStream.GetInterfacePtr(), adPersistXML); //old trick, call Save 

            // 3. Persist it to DOM Document
            IXMLDOMDocumentPtr pXMLDOMDoc;
            pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument));
            hr = pRs->Save(pXMLDOMDoc.GetInterfacePtr(), adPersistXML);
            // if you want to check out the content call printf(pXMLDOMDoc->Getxml());

            //Recycle the Recordset object
            hr = pRs->Close();

            // 4. load the recordset back from the file by calling Open with MSPersist provider and adCmdFile.
            // the Recordset will be a ReadOnly, Forwardly only
            hr = pRs->Open("authors.xml","Provider=MSPersist;",adOpenForwardOnly,adLockReadOnly,adCmdFile);
            hr = pRs->Close();

            // 5. Load from IStream object, call Open, first param is pStream.GetInterfacePtr()

            // Set the steam object position to the beginning of the stream:
            pStream->Position = 0;

            // call Open, passing in vtMissing for connection string, see Q245485 for details
            hr = pRs->Open(pStream.GetInterfacePtr(),vtMissing, adOpenForwardOnly,adLockReadOnly,adCmdFile);

            hr = pRs->Close();

            // 6 .Load from DOM Document, call Open, first param is pXMLDOMDoc.GetInterfacePtr() and
            // pass in vtMissing for connection string, see Q245485

            hr = pRs->Open(pXMLDOMDoc.GetInterfacePtr(), vtMissing, adOpenForwardOnly, adLockReadOnly, adCmdFile);

            hr = pRs->Close();

            //Don't forget to clean up the stream object
            hr = pStream->Close();

            }
            catch(_com_error &e)
            {
                dump_error(e);
            }
}

void dump_error(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}

Nota:

El código de ejemplo proporcionado en este artículo contiene una referencia a MSXML 2.5 o anterior. Si se ha instalado una versión más reciente de MSXML en modo de reemplazo en el equipo, el código de ejemplo usará automáticamente esta nueva versión. Si se ha instalado una versión más reciente de MSXML en modo en paralelo en el equipo, el código puede usar la versión anterior.

Para ejecutar el código con MSXML 6.0, deben cambiarse las siguientes líneas de código:

  • Reemplazar:

    #import "C:\Program files\Common Files\System\Ado\msado15.dll" rename_namespace("MSXML") rename("EOF", "ADOEOF")
    
    #import "c:\winnt\system32\msxml.dll" by using namespace MSXML;
    

    Por:

    #import "C:\Program files\Common Files\System\Ado\msado15.dll" rename_namespace("MSXML2") rename("EOF", "ADOEOF")
    
    #import "c:\winnt\system32\msxml6.dll" using namespace MSXML2;
    
  • Reemplazar:

    pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument));
    

    Por:

    pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument60));
    

Para ejecutar el código con MSXML 6.0, deben cambiarse las siguientes líneas de código:

  • Reemplazar:

    #import "C:\Program files\Common Files\System\Ado\msado15.dll" rename_namespace("MSXML") rename("EOF", "ADOEOF")
    
    #import "c:\winnt\system32\msxml.dll" by using namespace MSXML;
    

    Por:

    #import "C:\Program files\Common Files\System\Ado\msado15.dll" rename_namespace("MSXML2") rename("EOF", "ADOEOF")
    
    #import "c:\winnt\system32\msxml6.dll" using namespace MSXML2;
    
  • Reemplazar:

    pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument));
    

    Por:

    pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument60));