📄 dbcommand.cpp_1
字号:
{
POSITION begin = inputParams.GetHeadPosition();
int size = inputParams.GetCount();
ASSERT(begin != NULL);
for (int i = 0; i < size; i++)
{
CStringA paramValue = inputParams.GetNext(begin);
ULONG ulCount = 0;
for (int l = ulCount; l < numParams; l++)
{
if (cmdInfo->paramTypes[l] == DBPARAMTYPE_INPUT || cmdInfo->paramTypes[l] == DBPARAMTYPE_INPUTOUTPUT)
{
ASSERT(!paramValue.IsEmpty());
if (!paramValue.IsEmpty())
{
_tcsncpy(m_arrParams[l].szValue, paramValue, paramValue.GetLength());
}
else
{
_tcsncpy(m_arrParams[l].szValue, "", strlen(""));
}
ulCount = l + 1;
}
}
}
}
// execute our command and get back a rowset
hr = command.Open(NULL, NULL, false);
if (SUCCEEDED(hr))
{
hr = GetResults(command, numParams);
}
return hr;
}
HRESULT DBCommand::Execute(CStringA& cmdName,
CStringA& connectionString,
StringList& inputParams,
IDataSourceCache *spDataSrcCache,
IMemoryCache *spBinaryCache)
{
// clear out any old results
Clean();
bool dsFromCache = false;
HRESULT hr = S_OK;
// get a dataconnection
CDataConnection datasource;
hr = GetDataConnection(connectionString, spDataSrcCache, datasource, dsFromCache);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// nothing we can do, we can't get a data connection, get out of here
return hr;
}
// if we got here, then we got a data connection somehow, either using the cache,
// or opening one on our own
// get information about this stored procedure's parameters
CmdInfo *cmdInfo = NULL;
bool infoFromCache = false;
hr = GetCmdInfo(cmdName,
connectionString,
spBinaryCache,
datasource,
&cmdInfo,
infoFromCache);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// if we failed, there is a chance that it is because our data connection was
// stale, try opening another one
hr = RecoverDataConnection(connectionString, spDataSrcCache, datasource, dsFromCache);
if (SUCCEEDED(hr))
{
// re-opening the connection worked, try again to get our cmd information
hr = GetCmdInfo(cmdName,
connectionString,
spBinaryCache,
datasource,
&cmdInfo,
infoFromCache);
}
}
// check to see if we could get our command info
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// nothing w can do, just get out
return hr;
}
// if we got here, the we were able to get information about our stored procedure
// so now execute that stored proc
hr = ExecuteCommand(datasource,
cmdInfo,
inputParams);
ASSERT(!FAILED(hr));
// not a whole lot of error checking we can do on the returned hr, if the execute
// command failed, we are going to return the bad hr
// close the data connection if we didn't get one from the cache
if (!dsFromCache)
datasource.Close();
// delete our command info structure if we didn't get it from the cache
if (!infoFromCache)
{
cmdInfo->paramTypes.RemoveAll();
delete cmdInfo;
}
return hr;
}
HRESULT DBCommand::RecoverDataConnection( CStringA& connectionString,
IDataSourceCache *spDataSrcCache,
CDataConnection& datasource,
bool& fromCache)
{
HRESULT hr = S_OK;
if (spDataSrcCache == NULL)
{
// if we weren't give a cache, just open the data connection and return the results
// also set the from cache flag to false
fromCache = false;
hr = datasource.Open(connectionString);
}
else
{
// if we were given a cache add a new data connection to it and return the results
// also set the from cache flag to true
fromCache = true;
hr = spDataSrcCache->Add(connectionString,connectionString, &datasource);
}
return hr;
}
HRESULT DBCommand::GetDataConnection(CStringA& connectionString,
IDataSourceCache *spDataSrcCache,
CDataConnection& datasource,
bool& fromCache)
{
HRESULT hr = S_OK;
if (spDataSrcCache != NULL)
{
// if we are given a cache, try to find the datasource in the cache
// using the connection string as the id
if (FAILED(spDataSrcCache->Lookup(connectionString, &datasource)))
{
// something went wrong in looking for the dataconnection in our
// cache, try to open a new one
hr = spDataSrcCache->Add(connectionString, connectionString, &datasource);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// if we failed here, that means that we could not add a new connection, there
// is nothing we can do at this point, just return the failing hr
return hr;
}
}
// indicate that we got a data connection from the cache
fromCache = true;
}
else
{
// if we weren't given a cache to use, just open the data connection normally
hr = datasource.Open(connectionString);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// nothing we can do if we fail here, just return the failing hr
return hr;
}
}
return hr;
}
HRESULT DBCommand::BuildCmdStringAndParams(CProcedureParameters& procInfo,
CString& cmdName,
CmdInfo* cmdInfo)
{
HRESULT hr = S_OK;
// go through each parameter and build our call string
bool first = true;
CStringA strTemp("? = ");
CStringA strCmd;
strCmd.Format("Call %s ", cmdName);
while (procInfo.MoveNext() == S_OK)
{
// store the type of the parameter
cmdInfo->paramTypes.Add((WORD)procInfo.m_nType);
// build the parameter list part of our cmd call string
switch (procInfo.m_nType)
{
case DBPARAMTYPE_RETURNVALUE:
strTemp += strCmd;
strCmd = strTemp;
break;
case DBPARAMTYPE_INPUT:
case DBPARAMTYPE_INPUTOUTPUT:
case DBPARAMTYPE_OUTPUT:
if (first)
{
strCmd += "(?";
first = false;
}
else
strCmd += ", ?";
break;
default:
break;
}
}
if (!first)
strCmd += ")";
cmdInfo->cmdCallString.Format("{ %s }", strCmd);
return hr;
}
HRESULT DBCommand::CreateAndStoreCmdInfo(CProcedureParameters& procInfo,
const CSession& session,
IMemoryCache *spBinaryCache,
CString& cmdName,
CString& connectionString,
CmdInfo** cmdInfo,
bool& infoFromCache)
{
ASSERT(cmdInfo != NULL);
if (cmdInfo == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
*cmdInfo = new CmdInfo();
infoFromCache = false;
ASSERT(*cmdInfo != NULL);
if (*cmdInfo == NULL)
{
// we don't have enough memory!
return E_OUTOFMEMORY;
}
// connect to get information about our stored procedure
hr = procInfo.Open(session, NULL, NULL, cmdName);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// if we can't get cmd information, nothing to do but return
return hr;
}
// get our cmd info
hr = BuildCmdStringAndParams(procInfo, cmdName, *cmdInfo);
ASSERT(!FAILED(hr));
if (FAILED(hr))
{
// nothing we can do, we just can't get cmd info
return hr;
}
if (spBinaryCache != NULL)
{
// try to add this info into the cache
if (SUCCEEDED(spBinaryCache->Add((LPCSTR)(cmdName + connectionString),
(void*)*cmdInfo,
sizeof(CmdInfo),
NULL,
NULL,
NULL,
NULL)))
{
// set this flag so nobody will delete cmdInfo
infoFromCache = true;
}
}
else
{
// we don't have a cache to use
infoFromCache = false;
}
procInfo.Close();
procInfo.ClearRecordMemory();
procInfo.FreeRecordMemory();
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -