大家看看我现在的,这个函数是我现在的,现在可以直接调用不返回参数的存储过程,但是如果有一个存储过程要返回一条记录,或者要返回一个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;
}
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;
}
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. 下面一段话对你比较有用一些:)
要用IID_IMultipleResults!
ADO的效率比起OLE_DB差不了太多
存储过程:
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;
}
CREATE PROCEDURE TZG2 @vch1 varchar(64) AS
select * From TZG WHERE TZG.name=@vch1
GO
将上面函数的WCHAR* wCmdString=L"TZG1";改成
WCHAR* wCmdString=L"TZG2 '唐志国'";就可以了
{
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;
}帮忙找找错误
Alt+F7定义DBINITCONSTANTS宏在Preprocessor definitions中,link中添加 oledb.lib