大家看看我现在的,这个函数是我现在的,现在可以直接调用不返回参数的存储过程,但是如果有一个存储过程要返回一条记录,或者要返回一个dataset的时候该怎么办啊?:
bool Query(const char* lpszQuery)
{
if(g_pDBCmd==NULL||lpszQuery==NULL)
return false; CComPtr<ICommandText> CmdText;
IRowset* pRowset=NULL;
DBPARAMS pParams;
     DBROWCOUNT pcRowsAffected;
HRESULT hr;
ZeroMemory(&pParams,sizeof(DBPARAMS));
if(FAILED(hr = g_pDBCmd->CreateCommand(NULL,IID_ICommandText,(LPUNKNOWN*)&CmdText)))
return false; USES_CONVERSION;
hr=CmdText->SetCommandText(DBGUID_DBSQL,T2OLE(lpszQuery));
if(FAILED(hr)){
return false;
}
hr=CmdText->Execute(NULL, IID_NULL, &pParams, &pcRowsAffected, (LPUNKNOWN*)&pRowset);
return FAILED(hr)?false:true;
}

解决方案 »

  1.   

    当然没有,如果放在 pRowset 中还用问么?首先输出参数怎么传递都不知道啊。而且如果有记录应该返回记录数,也就是在pcRowsAffected这里。
      

  2.   

    不说别的,(LPUNKNOWN*)&pRowset参数是指针的地址,怎么不可以做输出参数,一般大家只用ADO就足够了,OLE_DB很少有人用,我也没用过,不过相信楼主的问题很容易解决,我帮你找一下资料
      

  3.   

    MSDN中:
    HRESULT Execute (
       IUnknown     *pUnkOuter,
       REFIID        riid,
       DBPARAMS     *pParams,
       DBROWCOUNT   *pcRowsAffected,
       IUnknown    **ppRowset)注意第二个参数,MSDN对他的解释:
    riid 
    [in]
    The requested IID for the rowset returned in *ppRowset. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset. If the command has any open rowsets, requesting an interface that is not supported on those open rowsets will generally return E_NOINTERFACE as it is not possible to change the properties supported on a command with open rowsets. In addition, specifying the IID of a nonmandatory interface that has not been explicitly requested through rowset properties set on a prepared command might reduce the provider's ability to optimize the command, because the provider might have to rebuild the access plan to satisfy the additional interface. 
    If this is IID_NULL, ppRowset is ignored and no rowset is returned, even if the command would otherwise generate a rowset. Specifying IID_NULL is useful in the case of text commands that do not generate rowsets, such as data definition commands, as a hint to the provider that no rowset properties need to be verified. If riid is IID_IMultipleResults, the provider creates a multiple results object and returns a pointer to it in *ppRowset; it does this even if the command generates a single result. If the provider supports multiple results and the command generates multiple results but riid is not IID_IMultipleResults, the provider returns the first result and discards any remaining results. If riid is IID_IMultipleResults and the provider does not support multiple results, ICommand::Execute returns E_NOINTERFACE. 下面一段话对你比较有用一些:)
      

  4.   

    老大,我有MSDN这个也看过了,拜托弄点实际点的东东吧。用OLE DB的理由很简单,因为要效率。ADO的效率,呵呵,不敢恭维啊。
      

  5.   

    老大,IID_NULL当然不会返回结果集,你既然看了MSND,为什么还要用IID_NULL?
    要用IID_IMultipleResults!
    ADO的效率比起OLE_DB差不了太多
      

  6.   

    你测试过么?呵呵,我测试过。差太远,至少是4倍。你没有看清楚我内容啊,“这个函数是我现在的,现在可以直接调用不返回参数的存储过程”我要得就是怎么改,可以支持out输出参数。而且你说得用IID_IMultipleResults也是错得,这个是在多结果集得时候用的,普通情况下用根本用不着它。
      

  7.   

    说明:调用没用参数的存储过程,返回记录集的例子:DSN:TestDB
    存储过程:
    CREATE PROCEDURE TZG1  AS
    select * From TZG
    GO数据库:1个int字段,一个varchar字段 表名TZG的SQLSERVER数据库,测试成功:带参数的存储过程稍后可以给出,这些简单的东东搞了我一上午// OLEDB.cpp : Defines the entry point for the application.
    //#include "stdafx.h"
    #include "oledb.h"
    #include "oledberr.h"
    #include "msdaguid.h"
    #include "msdasql.h"
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
      // TODO: Place code here.
    IDBInitialize *pIDBInit=NULL;
    IDBProperties *pIDBProp=NULL;
    DBPROP InitPropties[4];
    DBPROPSET rgInitPropSet[1];
    int i=0;
    IDBCreateSession *pCreateSession=NULL;
    IDBCreateCommand *pCreateCommand=NULL;
    ICommandText *pCommandText=NULL;
    // WCHAR* wCmdString=L"Select * From TZG";
    WCHAR* wCmdString=L"TZG1";
    IRowset* pRowset=NULL;
    long lNumRows;
    CoInitialize(NULL);
    CoCreateInstance(CLSID_MSDASQL,NULL,CLSCTX_INPROC_SERVER,IID_IDBInitialize,(void**)&pIDBInit); for(i=0;i<4;i++)
    {
    VariantInit(&InitPropties[i].vValue);
    InitPropties[i].dwOptions=DBPROPOPTIONS_REQUIRED;
    InitPropties[i].colid=DB_NULLID;
    } InitPropties[0].dwPropertyID=DBPROP_INIT_PROMPT;
    InitPropties[0].vValue.vt=VT_I2; InitPropties[1].dwPropertyID=DBPROP_AUTH_USERID;
    InitPropties[1].vValue.vt=VT_BSTR;
    InitPropties[1].vValue.bstrVal=SysAllocString(L""); InitPropties[2].dwPropertyID=DBPROP_AUTH_PASSWORD;
    InitPropties[2].vValue.vt=VT_BSTR;
    InitPropties[2].vValue.bstrVal=SysAllocString(L"");

    InitPropties[3].dwPropertyID=DBPROP_INIT_DATASOURCE;
    InitPropties[3].vValue.vt=VT_BSTR;
    InitPropties[3].vValue.bstrVal=SysAllocString(L"TestDB"); rgInitPropSet[0].guidPropertySet=DBPROPSET_DBINIT;
    rgInitPropSet[0].cProperties=4;
    rgInitPropSet[0].rgProperties=InitPropties;

    pIDBInit->QueryInterface(IID_IDBProperties,(void**)&pIDBProp);
    pIDBProp->SetProperties(1,rgInitPropSet);
    pIDBProp->Release(); pIDBInit->Initialize(); pIDBInit->QueryInterface(IID_IDBCreateSession,(void**)&pCreateSession);
    pCreateSession->CreateSession(NULL,IID_IDBCreateCommand,(IUnknown**)&pCreateCommand);
    pCreateCommand->CreateCommand(NULL,IID_ICommandText,(IUnknown**)&pCommandText);

    pCommandText->SetCommandText(DBGUID_DBSQL,wCmdString); HRESULT hr;
    hr=pCommandText->Execute(NULL,IID_IRowset,NULL,&lNumRows,(IUnknown**)&pRowset);
    if(SUCCEEDED(hr))
    {
    IColumnsInfo* pColumnsInfo=NULL;
    unsigned long lNumCols=0;
    DBCOLUMNINFO *pDBColumnInfo=NULL;
    WCHAR *pStringsBuffer;
    pRowset->QueryInterface(IID_IColumnsInfo,(void**)&pColumnsInfo);
    pColumnsInfo->GetColumnInfo(&lNumCols,&pDBColumnInfo,&pStringsBuffer);
    pColumnsInfo->Release(); DBBINDING *pBindings=NULL;
    unsigned long j=0;
    pBindings=new DBBINDING[lNumCols];
    long cbColOffset=0;
    for(j=0;j<lNumCols;j++)
    {
    pBindings[j].iOrdinal=j+1;
    pBindings[j].obValue=cbColOffset;
    pBindings[j].obLength=0;
    pBindings[j].obStatus=0;
    pBindings[j].pTypeInfo=NULL;
    pBindings[j].pObject=NULL;
    pBindings[j].pBindExt=NULL;
    pBindings[j].dwPart=DBPART_VALUE;
    pBindings[j].dwMemOwner=DBMEMOWNER_CLIENTOWNED;
    pBindings[j].eParamIO=DBPARAMIO_NOTPARAM;
    pBindings[j].cbMaxLen=pDBColumnInfo[j].ulColumnSize;
    pBindings[j].dwFlags=0;
    pBindings[j].wType=pDBColumnInfo[j].wType;
    pBindings[j].bPrecision=pDBColumnInfo[j].bPrecision;
    pBindings[j].bScale=pDBColumnInfo[j].bScale;
    cbColOffset=cbColOffset+pDBColumnInfo[j].ulColumnSize;
    } IAccessor* pAccessor=NULL;
    HACCESSOR hAccessor;
    pRowset->QueryInterface(IID_IAccessor,(void**)&pAccessor);
    pAccessor->CreateAccessor(DBACCESSOR_ROWDATA,lNumCols,pBindings,0,&hAccessor,NULL);
    for(j=0;j<lNumCols;j++)
    {
    pDBColumnInfo[j].pwszName=pDBColumnInfo[j].pwszName;
    }
    unsigned long lNumRowRetrieved=0;
    HROW hRows[5];
    HROW *pRows=&hRows[0];
    char *pBuffer;
    pRowset->GetNextRows(0,0,5,&lNumRowRetrieved,&pRows);
    pBuffer=new char[cbColOffset];
    while(lNumRowRetrieved>0)
    {
    for(j=0;j<lNumRowRetrieved;j++)
    {
    memset(pBuffer,0,cbColOffset);
    pRowset->GetData(hRows[j],hAccessor,pBuffer);
    int aa=pBuffer[pBindings[0].obValue];
    char *bb=(char*)&pBuffer[pBindings[1].obValue];
    }
    pRowset->ReleaseRows(lNumRowRetrieved,hRows,NULL,NULL,NULL);
    pRowset->GetNextRows(0,0,5,&lNumRowRetrieved,&pRows);
    }
    delete []pBuffer;
    pAccessor->ReleaseAccessor(hAccessor,NULL);
    pAccessor->Release();
    delete []pBindings;
    }
    pRowset->Release();
    pCommandText->Release();
    pCreateCommand->Release();
    pCreateSession->Release();
    pIDBInit->Uninitialize();
    pIDBInit->Release(); SysFreeString(InitPropties[1].vValue.bstrVal);
    SysFreeString(InitPropties[2].vValue.bstrVal);
    SysFreeString(InitPropties[3].vValue.bstrVal);
    CoUninitialize();
    return 0;
    }
      

  8.   

    待参数的存储过程只要简单地把命令字符串后面添加参数就可以了,比如
    CREATE PROCEDURE TZG2  @vch1 varchar(64) AS
    select * From TZG WHERE TZG.name=@vch1
    GO
    将上面函数的WCHAR* wCmdString=L"TZG1";改成
    WCHAR* wCmdString=L"TZG2 '唐志国'";就可以了
      

  9.   

    不怎么对哦。看看我这里哪里错了。bool DoQuery(const char* lpszQuery,int& count)
    {
    if(g_pDBCmd==NULL||lpszQuery==NULL)
    return false;// Structure supporting the parameters of the example stored procedure.
    typedef struct tagSPROCPARAMS
        {
    int        lReturnValue;
    int        ccccc;
        } SPROCPARAMS;    // Interfaces used in the example.
    CComPtr<ICommandText> pICommandText;
        ICommandWithParameters* pICommandWithParameters = NULL;
        IAccessor*          pIAccessor = NULL;
        IMultipleResults*   pIMultipleResults = NULL;
        IRowset*            pIRowset = NULL;    // Command parameter data.
        DBPARAMS            Params;
        const ULONG         nParams = 2;
        DBPARAMBINDINFO     rgParamBindInfo[nParams] = 
            {
            L"DBTYPE_I4",
            L"i1",
            sizeof(long),
            DBPARAMFLAGS_ISINPUT,
            11,
            0,
            L"DBTYPE_I4",
            L"@out",
            sizeof(long),
            DBPARAMFLAGS_ISOUTPUT,
            0,
            0 };
        ULONG               rgParamOrdinals[nParams] = {1,2};    // Parameter accessor data.
        HACCESSOR           hAccessor;
        DBBINDING           acDBBinding[nParams];
        DBBINDSTATUS        acDBBindStatus[nParams];    // The command and parameter data.
        WCHAR*              wszSQLString =
            L"{exec test ?,?}";
        SPROCPARAMS         sprocparams = {5, 4};    // Returned count of rows affected.
        LONG                cRowsAffected = 0;    HRESULT             hr;
        
    if(FAILED(hr = g_pDBCmd->CreateCommand(NULL,IID_ICommandText,(LPUNKNOWN*)&pICommandText)))
    return false;    // Set the command text value.
        if (FAILED(hr = pICommandText->SetCommandText(DBGUID_DBSQL,
            wszSQLString)))
        {
        // Process error from ICommand and return.
        }    // Get the ICommandWithParameters interface to set up parameter
        // values.
        if (FAILED(hr = pICommandText->QueryInterface(
            IID_ICommandWithParameters,
            (void**) &pICommandWithParameters)))
            {
            // Process error from ICommand and return.
            }    // Set parameter information.
        if (FAILED(hr = pICommandWithParameters->SetParameterInfo(nParams, 
            rgParamOrdinals, rgParamBindInfo)))
            {
            // 这里hr返回得是DB_S_TYPEINFOOVERRIDDEN
            // Process error from ICommandWithParameters and return.
            }    // Create parameter accessor, but first set binding structures
        // to indicate the characteristics of each parameter.
        for (ULONG 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;
            }    acDBBinding[0].iOrdinal = 1;
        acDBBinding[0].obValue = offsetof(SPROCPARAMS, lReturnValue);
        acDBBinding[0].eParamIO = DBPARAMIO_INPUT;
        acDBBinding[0].cbMaxLen = sizeof(long);
        acDBBinding[0].wType = DBTYPE_I4;
        acDBBinding[0].bPrecision = 11;    acDBBinding[1].iOrdinal = 2;
        acDBBinding[1].obValue = offsetof(SPROCPARAMS, ccccc);
        acDBBinding[1].eParamIO = DBPARAMIO_OUTPUT;
        acDBBinding[1].cbMaxLen = sizeof(long);
        acDBBinding[1].wType = DBTYPE_I4;
        acDBBinding[1].bPrecision = 11;    // Get the IAccessor interface, then create the accessor for
        // the defined parameters.
        pICommandWithParameters->QueryInterface(IID_IAccessor,
            (void**) &pIAccessor);    hr = pIAccessor->CreateAccessor(DBACCESSOR_PARAMETERDATA,
            nParams, acDBBinding, sizeof(SPROCPARAMS), &hAccessor,
            acDBBindStatus);
        if (FAILED(hr))
            {
            // Process error from IAccessor and return.
            }    // Fill the DBPARAMS structure for the command execution.
        Params.pData = &sprocparams;
        Params.cParamSets = 1;
        Params.hAccessor = hAccessor;
        
        // Execute the command.
        if (FAILED(hr = pICommandText->Execute(NULL, IID_IMultipleResults,
            &Params, &cRowsAffected, (IUnknown**) &pIMultipleResults)))
    return false;// 这里hr返回得是DB_E_ERRORSINCOMMAND
    else
    return true;
    }帮忙找找错误
      

  10.   

    晕,来就出错。dfdsaf error LNK2001: 无法解析的外部符号 "struct _GUID const CLSID_MSDASQL" (?CLSID_MSDASQL@@3U_GUID@@B)
      

  11.   

    你有没有即时通讯工具啊?QQ,MSN?这样太慢了
      

  12.   

    你原来还没试,我以为你知道
    Alt+F7定义DBINITCONSTANTS宏在Preprocessor definitions中,link中添加 oledb.lib