appendchunkx.cpp

来自「visual c++ 很全的ado的sample」· C++ 代码 · 共 227 行

CPP
227
字号
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#define ChunkSize	100

#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "malloc.h"
#include "AppendChunkX.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AppendChunkX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
	HRESULT  hr = S_OK;

	if(FAILED(::CoInitialize(NULL)))
		return;
	
	AppendChunkX();
		
	//Wait here for the user to see the output
	printf("\n\nPress any key to continue..");
	getch();
	::CoUninitialize();
}


///////////////////////////////////////////////////////////
//                                                       //
//      AppendChunkX Function                            //
//                                                       //
///////////////////////////////////////////////////////////
VOID  AppendChunkX(VOID)
{
	// Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
	 _RecordsetPtr pRstPubInfo = NULL;
	 _ConnectionPtr pConnection = NULL;
	
	  //Define other variables
	  IADORecordBinding   *picRs = NULL;  //Interface Pointer declared.(VC++ Extensions)   
	  CPubInfoRs pubrs;          //C++ class object   

	  HRESULT hr = S_OK;
	 _bstr_t strCnn("Provider=sqloledb;Data Source=srv;"
			"Initial Catalog=pubs;User Id=sa;Password=;");
	 
	 _bstr_t strMessage,strPubID,strPRInfo;
	 _variant_t varChunk;
	 long lngOffSet,lngLogoSize;
 	 char pubId[50];
	 lngOffSet = 0;    
 	  
	 UCHAR chData;
	 CHAR ch;
	 SAFEARRAY FAR *psa;
	 SAFEARRAYBOUND rgsabound[1];
	 rgsabound[0].lLbound = 0;
	 rgsabound[0].cElements = ChunkSize;

    try
    {
        //Open a Connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr = pConnection->Open(strCnn,"","",NULL);

        TESTHR(hr= pRstPubInfo.CreateInstance(__uuidof(Recordset)));  

        pRstPubInfo->CursorType = adOpenKeyset;
        pRstPubInfo->LockType = adLockOptimistic;

        hr = pRstPubInfo->Open("pub_info",
            _variant_t((IDispatch*)pConnection,true),
            adOpenKeyset,adLockOptimistic,adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use 
        //for Binding Recordset to a class    
        TESTHR(pRstPubInfo->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs);

        //Bind the Recordset to a C++ Class here    
        TESTHR(picRs->BindToRecordset(&pubrs));

        //Display the available logos here
        strMessage = "Available logos are: " + (_bstr_t)"\n\n";
        printf(strMessage);
        int Counter = 0;
        while(!(pRstPubInfo->EndOfFile))
        { 
            printf("\n%s",pubrs.m_sz_pubid);
            printf("\n%s",strtok(pubrs.m_sz_prinfo,","));

            //Display 5 records at a time and wait for user to continue..
            if (++Counter >= 5)
            {
                Counter = 0;
                printf("\nPress any key to continue...");
                getch();
            }
            pRstPubInfo->MoveNext(); 
        }

        //Prompt For a Logo to Copy
        printf("\nEnter the ID of a logo to copy: ");
        scanf("%s",pubId);
        strPubID = pubId;

        //Copy the logo to a variable in chunks

        pRstPubInfo->Filter = "pub_id = '"  + strPubID + "'";
        lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;

        //Create a safe array to store the array of BYTES  
        rgsabound[0].cElements = lngLogoSize;
        psa = SafeArrayCreate(VT_UI1,1,rgsabound);

        long index1 = 0;
        while(lngOffSet < lngLogoSize)
        {
            varChunk = pRstPubInfo->Fields->
                        Item["logo"]->GetChunk(ChunkSize);

            //Copy the data only upto the Actual Size of Field.  
            for(long index=0;index<=(ChunkSize-1);index++)
            {
                hr= SafeArrayGetElement(varChunk.parray,&index,&chData);
                if(SUCCEEDED(hr))
                {
                    //Take BYTE by BYTE and advance Memory Location
                    hr = SafeArrayPutElement(psa,&index1,&chData); 
                    index1++;
                }
                else
                    break;
            }
            lngOffSet = lngOffSet + ChunkSize;
        }
        lngOffSet = 0;

        printf("Enter a new Pub Id: ");
        scanf("%s",pubrs.m_sz_pubid);
        strPubID = pubrs.m_sz_pubid;
        printf("Enter descriptive text: " );
        scanf("%c",&ch);
        gets(pubrs.m_sz_prinfo);
        
        pRstPubInfo->AddNew();
        pRstPubInfo->Fields->GetItem("pub_id")->PutValue(strPubID);
        pRstPubInfo->Fields->GetItem("pr_info")->
            PutValue(pubrs.m_sz_prinfo);

        //Assign the Safe array  to a variant. 
        varChunk.vt = VT_ARRAY|VT_UI1;
        varChunk.parray = psa;
        hr = pRstPubInfo->Fields->GetItem("logo")->
                AppendChunk(varChunk); 

        //Update the table 
        pRstPubInfo->Update();

        lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;

        //Show the newly added record.
        printf("New Record : %s\n Description : %s\n Logo Size : %s",
            pubrs.m_sz_pubid,
            pubrs.m_sz_prinfo,(LPCSTR)(_bstr_t)pRstPubInfo->Fields->
            Item["logo"]->ActualSize);

        //Delete new record because this is demonstration.
        pConnection->Execute("DELETE FROM PUB_INFO WHERE pub_id = '"
                        + strPubID +"'",NULL,adCmdText);

        pRstPubInfo->Close();
        pConnection->Close();
    }

    catch(_com_error &e)
	{
		 // Notify the user of errors if any.
		_bstr_t bstrSource(e.Source());
		_bstr_t bstrDescription(e.Description());

		PrintProviderError(pConnection);
		printf("Source : %s \n Description : %s\n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);

	}
}


///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
	// Print Provider Errors from Connection object.
	// pErr is a record object in the Connection's Error collection.
	ErrorPtr    pErr  = NULL;
	long      nCount	= 0;    
	long      i     = 0;

	if( (pConnection->Errors->Count) > 0)
	{
		nCount = pConnection->Errors->Count;
		// Collection ranges from 0 to nCount -1.
		for(i = 0; i < nCount; i++)
		{
			pErr = pConnection->Errors->GetItem(i);
			printf("\t Error number: %x\t%s", pErr->Number,(LPCSTR) pErr->Description);
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?