//给你一段代码:// section 1:
drop function fn_RectangleArea
go
CREATE FUNCTION fn_RectangleArea
   (@Width int, 
@Height int )
RETURNS int
AS
BEGIN
   RETURN ( @Width * @Height )
END
GOHere is a sample code./*
Example shows how to execute user-defined functions and process return code value.
*/
void InitializeAndEstablishConnection();
#define UNICODE
#define DBINITCONSTANTS
#define INITGUID
#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <iostream.h>
#include <oledb.h>
#include <oledberr.h>
#include <sqloledb.h>IDBInitialize*      pIDBInitialize          = NULL;    
IDBCreateSession*   pIDBCreateSession       = NULL;
IDBCreateCommand*   pIDBCreateCommand       = NULL;
ICommandText*       pICommandText           = NULL;
IRowset*            pIRowset                = NULL;
ICommandWithParameters* pICommandWithParams = NULL;
IAccessor*          pIAccessor              = NULL;
IDBProperties*      pIDBProperties          = NULL;
WCHAR*              pStringsBuffer;
DBBINDING*          pBindings;
const ULONG         nInitProps = 4;
DBPROP              InitProperties[nInitProps];    
const ULONG         nPropSet = 1;
DBPROPSET           rgInitPropSet[nPropSet];            
HRESULT             hr;
HACCESSOR           hAccessor;
const ULONG         nParams = 3; //No. of parameters in the command
DBPARAMBINDINFO     ParamBindInfo[nParams];
ULONG               i;
ULONG               cbColOffset = 0;ULONG               ParamOrdinals[nParams];
LONG                cNumRows = 0;
DBPARAMS            Params;
/*
Declare an array of DBBINDING structures, one for each parameter
in the command
*/
DBBINDING           acDBBinding[nParams];
DBBINDSTATUS        acDBBindStatus[nParams];//The following buffer is used to store parameter values.
typedef struct tagSPROCPARAMS
{
    long    lReturnValue;
    long    inParam1;
    long    inParam2;
} SPROCPARAMS;
  
void main() {    //The command to execute.
 WCHAR* wCmdString = L"{? = CALL fn_RectangleArea(?, ?) }";
// WCHAR* wCmdString = L"EXEC ? = fn_RectangleVolume(?, ?)";    SPROCPARAMS sprocparams = {0,5,10};    //All the initialization stuff in a separate function.
    InitializeAndEstablishConnection();    //Let us create a new session from the data source object.
    if(FAILED(pIDBInitialize->QueryInterface(
                                    IID_IDBCreateSession,
                                    (void**) &pIDBCreateSession)))
    {
        cout << "Failed to access IDBCreateSession interface\\n";
        goto EXIT;
    }
    if(FAILED(pIDBCreateSession->CreateSession(
                                        NULL, 
                                        IID_IDBCreateCommand, 
                                        (IUnknown**) &pIDBCreateCommand)))
    {
        cout << "pIDBCreateSession->CreateSession failed\\n";
        goto EXIT;
    }    //Create a Command
    if(FAILED(pIDBCreateCommand->CreateCommand(
                                        NULL, 
                                        IID_ICommandText, 
                                        (IUnknown**) &pICommandText)))
    {
        cout << "Failed to access ICommand interface\\n";
        goto EXIT;
    }
    
    //Set the command text.
    if(FAILED(pICommandText->SetCommandText(DBGUID_DBSQL, wCmdString)))
    {
        cout << "failed to set command text\\n";
        goto EXIT;
    }    /*
    Describe the command parameters (parameter name, provider
    specific name of the parameter's data type etc.) in an array of 
    DBPARAMBINDINFO structures.  This information is then used by
    SetParameterInfo().
    */
    ParamBindInfo[0].pwszDataSourceType = L"DBTYPE_I4";
    ParamBindInfo[0].pwszName = NULL; // L"ReturnVal"; //return value from sp
    ParamBindInfo[0].ulParamSize = sizeof(long);
    ParamBindInfo[0].dwFlags = DBPARAMFLAGS_ISOUTPUT;
    ParamBindInfo[0].bPrecision = 11;
    ParamBindInfo[0].bScale = 0;
    ParamOrdinals[0] = 1;
    
    ParamBindInfo[1].pwszDataSourceType = L"DBTYPE_I4";
    ParamBindInfo[1].pwszName = NULL;      //L"@inparam1";               
    ParamBindInfo[1].ulParamSize = sizeof(long);
    ParamBindInfo[1].dwFlags = DBPARAMFLAGS_ISINPUT;
    ParamBindInfo[1].bPrecision = 11;
    ParamBindInfo[1].bScale = 0;
    ParamOrdinals[1] = 2;    ParamBindInfo[2].pwszDataSourceType = L"DBTYPE_I4";
    ParamBindInfo[2].pwszName = NULL;      // L"@inparam2"; 
    ParamBindInfo[2].ulParamSize = sizeof(long);
    ParamBindInfo[2].dwFlags = DBPARAMFLAGS_ISINPUT;
    ParamBindInfo[2].bPrecision = 11;
    ParamBindInfo[2].bScale = 0;
    ParamOrdinals[2] = 3;    //Set the parameters information.
    if(FAILED(pICommandText->QueryInterface(
                                    IID_ICommandWithParameters,
                                    (void**)&pICommandWithParams)))
    {
        cout << "failed to obtain ICommandWithParameters\\n";
        goto EXIT;
    }
    if(FAILED(pICommandWithParams->SetParameterInfo(
                                        nParams, 
                                        ParamOrdinals, 
                                        ParamBindInfo)))
    {
        cout << "failed in setting parameter info.(SetParameterInfo)\\n";
        goto EXIT;
    }    //Let us describe the consumer buffer by filling in the array 
    //of DBBINDING structures.  Each binding associates
    //a single parameter to the consumer's buffer.
    for(i = 0; i < nParams; i++)
    {
        acDBBinding[i].obLength = 0;
        acDBBinding[i].obStatus = 0;
        acDBBinding[i].pTypeInfo = NULL;
        acDBBinding[i].pObject = NULL;
        acDBBinding[i].pBindExt = NULL;
        acDBBinding[i].dwPart = DBPART_VALUE;
        acDBBinding[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
        acDBBinding[i].dwFlags = 0;
        acDBBinding[i].bScale = 0;
    } //for    acDBBinding[0].iOrdinal = 1;
    acDBBinding[0].obValue = offsetof(SPROCPARAMS, lReturnValue);
    acDBBinding[0].eParamIO = DBPARAMIO_OUTPUT;
    acDBBinding[0].cbMaxLen = sizeof(long);
    acDBBinding[0].wType = DBTYPE_I4;
    acDBBinding[0].bPrecision = 11;
    
    acDBBinding[1].iOrdinal = 2;
    acDBBinding[1].obValue = offsetof(SPROCPARAMS, inParam1);
    acDBBinding[1].eParamIO = DBPARAMIO_INPUT;
    acDBBinding[1].cbMaxLen = sizeof(long);
    acDBBinding[1].wType = DBTYPE_I4;
    acDBBinding[1].bPrecision = 11;

解决方案 »

  1.   

    // section 2:    
        acDBBinding[2].iOrdinal = 3;
        acDBBinding[2].obValue = offsetof(SPROCPARAMS, inParam2);
        acDBBinding[2].eParamIO = DBPARAMIO_INPUT;
        acDBBinding[2].cbMaxLen = sizeof(long);
        acDBBinding[2].wType = DBTYPE_I4;
        acDBBinding[2].bPrecision = 11;    //Let us create an accessor from the above set of bindings.
        hr = pICommandWithParams->QueryInterface(
                                        IID_IAccessor, 
                                        (void**)&pIAccessor);
        if (FAILED(hr))
        {
            cout << "Failed to get IAccessor interface\\n";
        }    hr = pIAccessor->CreateAccessor(
                                DBACCESSOR_PARAMETERDATA,
                                nParams, 
                                acDBBinding, 
                                sizeof(SPROCPARAMS), 
                                &hAccessor,
                                acDBBindStatus);
        if (FAILED(hr))
        {
            cout << "failed to create accessor for the defined parameters\\n";
        }
        /*
        Fill in DBPARAMS structure for the command execution. This structure
        specify the parameter values in the command.  This structure is
        then passed to Execute.
        */
        Params.pData = &sprocparams;
        Params.cParamSets = 1;
        Params.hAccessor = hAccessor;
        
        //Execute the command.
        if(FAILED(hr = pICommandText->Execute(
                                        NULL, 
                                        IID_IRowset, 
                                        &Params, 
                                        &cNumRows, 
                                        (IUnknown **) &pIRowset)))    
        {
            cout << "failed to execute command\\n";
            goto EXIT;
        }    printf("  Return value = %d\n", sprocparams.lReturnValue);    //we are not interested in the resultset so release it 
        //without processing.
       if (pIRowset != NULL)
          pIRowset->Release();
        //Free up memory.
        pIAccessor->ReleaseAccessor(hAccessor, NULL);
        pIAccessor->Release();
        pICommandWithParams->Release();
        pICommandText->Release();
        pIDBCreateCommand->Release();
        pIDBCreateSession->Release();    
        if(FAILED(pIDBInitialize->Uninitialize()))
        {
            //Uninitialize is not required, but it fails if an interface
            //has not not been released.  This can be used for debugging.
            cout << "Problem uninitializing\\n";
        } //if
        pIDBInitialize->Release();
        
        //Release COM.
        CoUninitialize();
        return;EXIT:
        if(pIAccessor != NULL)
            pIAccessor->Release();
        if(pICommandWithParams != NULL)
            pICommandWithParams->Release();
        if(pICommandText != NULL)
            pICommandText->Release();
        if(pIDBCreateCommand != NULL)
            pIDBCreateCommand->Release();
        if(pIDBCreateSession != NULL)
           pIDBCreateSession->Release();
        if (pIDBInitialize != NULL)
        {
            if (FAILED(pIDBInitialize->Uninitialize()))
            {
                //Uninitialize is not required, but it fails if an
                //interface has not been released.  This can be used
                //for debugging.
                cout << "problem in uninitializing\\n";
            } //if inner
            pIDBInitialize->Release();
        } //if outer    CoUninitialize();
    }
    //---------------------------------------------------------------
    void InitializeAndEstablishConnection()
    {    
        //Initialize the COM library.
        CoInitialize(NULL);    //Obtain access to the SQLOLEDB provider.    
        hr = CoCreateInstance(
                        CLSID_SQLOLEDB, 
                        NULL, 
                        CLSCTX_INPROC_SERVER,
                        IID_IDBInitialize, 
                        (void **) &pIDBInitialize);
        if (FAILED(hr))
        {
            cout << "Failed in CoCreateInstance()\\n";
        }    /*
        Let us initialize the property values needed
        to establish the connection.
        */
        for(i = 0; i < nInitProps; i++)
            VariantInit(&InitProperties[i].vValue);
        //Specify server name.
        InitProperties[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
        InitProperties[0].vValue.vt = VT_BSTR;
        InitProperties[0].vValue.bstrVal = 
                                    SysAllocString(L"server");
        InitProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
        InitProperties[0].colid = DB_NULLID;    //Specify database name.
        InitProperties[1].dwPropertyID = DBPROP_INIT_CATALOG;
        InitProperties[1].vValue.vt = VT_BSTR;
        InitProperties[1].vValue.bstrVal = 
                                    SysAllocString(L"database");
        InitProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;
        InitProperties[1].colid = DB_NULLID;    //Specify user name (login).
        InitProperties[2].dwPropertyID = DBPROP_AUTH_USERID; 
        InitProperties[2].vValue.vt = VT_BSTR;
        InitProperties[2].vValue.bstrVal = 
                                    SysAllocString(L"login");
        InitProperties[3].dwOptions = DBPROPOPTIONS_REQUIRED;
        InitProperties[3].colid = DB_NULLID;    //Specify password.
        InitProperties[3].dwPropertyID = DBPROP_AUTH_PASSWORD;
        InitProperties[3].vValue.vt = VT_BSTR;
        InitProperties[3].vValue.bstrVal = SysAllocString(L"password");
        InitProperties[3].dwOptions = DBPROPOPTIONS_REQUIRED;
        InitProperties[3].colid = DB_NULLID;    /*
        Now that properties are set, construct the DBPROPSET structure
        (rgInitPropSet).  The DBPROPSET structure is used to pass an array
        of DBPROP structures (InitProperties) to SetProperties method.
        */
        rgInitPropSet[0].guidPropertySet = DBPROPSET_DBINIT;
        rgInitPropSet[0].cProperties = 4;
        rgInitPropSet[0].rgProperties = InitProperties;    //Set initialization properties.
        hr = pIDBInitialize->QueryInterface(
                                    IID_IDBProperties, 
                                    (void **)&pIDBProperties);
        if (FAILED(hr))
        {
            cout << "Failed to obtain IDBProperties interface.\\n";
        }    hr = pIDBProperties->SetProperties(
                                    nPropSet, 
                                    rgInitPropSet);
        if(FAILED(hr))
        {
            cout << "Failed to set initialization properties\\n";
        }
        pIDBProperties->Release();    //Now we establish connection to the data source.
        if(FAILED(pIDBInitialize->Initialize()))
        {
            cout << "Problem in initializing\\n";
        }
    } //end of InitializeAndEstablishConnection.// -- the end --
      

  2.   

    大哥,这么长的代码我一下子看不过来,可不可以给我大致讲解一下原理,用到了OLE_DB中那些东西