📄 dbrfx.cpp
字号:
#ifdef _UNICODE
case CFieldExchange::BindFieldForUpdate:
if (pFX->m_prs->m_nProxyFields != 0)
{
// Fill buffer (expected by SQLSetPos) with new field data
USES_CONVERSION;
LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
lstrcpyA(lpszData, T2A((LPCTSTR)value));
pFX->Default(szName, (void *)lpszData, plLength, SQL_C_CHAR,
lstrlenA(lpszData), nMaxLength);
}
return;
#endif // _UNICODE
case CFieldExchange::Fixup:
if (*plLength == SQL_NULL_DATA)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value[0] = '\0';
}
else
{
#ifdef _UNICODE
// Copy value out of the proxy
value = (LPTSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
#endif
LPTSTR lpsz = value;
if (pFX->m_prs->m_pDatabase->m_bStripTrailingSpaces)
{
// find first trailing space
LPTSTR lpszFirstTrailing = NULL;
while (*lpsz != '\0')
{
if (*lpsz != ' ')
lpszFirstTrailing = NULL;
else
{
if (lpszFirstTrailing == NULL)
lpszFirstTrailing = lpsz;
}
lpsz = _tcsinc(lpsz);
}
// truncate
if (lpszFirstTrailing != NULL)
*lpszFirstTrailing = '\0';
}
*plLength = lstrlen(value);
}
return;
case CFieldExchange::SetFieldNull:
if ((pFX->m_pvField == NULL &&
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
pFX->m_pvField == value)
{
if (pFX->m_bField)
{
// Mark fields null
pFX->m_prs->SetNullFieldStatus(nField - 1);
// Set string 0 length
*plLength = SQL_NULL_DATA;
}
else
{
pFX->m_prs->ClearNullFieldStatus(nField - 1);
*plLength = SQL_NTS;
}
#ifdef _DEBUG
pFX->m_nFieldFound = nField;
#endif
}
return;
#ifdef _UNICODE
case CFieldExchange::NameValue:
if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
{
*pFX->m_pstr += szName;
*pFX->m_pstr += '=';
}
// Fall through
case CFieldExchange::Value:
if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
{
// Get the field data
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
if (pFX->m_prs->IsFieldStatusNull(nField - 1))
{
*plLength = SQL_NULL_DATA;
}
else
{
USES_CONVERSION;
lstrcpyA(lpszData, T2A((LPCTSTR)value));
*plLength = lstrlen(value);
}
// If optimizing for bulk add, only need lengths & proxy set correctly
if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
{
*pFX->m_pstr += '?';
*pFX->m_pstr += pFX->m_lpszSeparator;
pFX->m_nParamFields++;
AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
(UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
SQL_C_CHAR, pODBCInfo->m_nSQLType, nMaxLength,
pODBCInfo->m_nScale, lpszData, 0, plLength));
}
}
return;
#endif // _UNICODE
case CFieldExchange::MarkForAddNew:
// can force writing of psuedo-null value (as a non-null) by setting field dirty
if (*value != '\0')
{
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
pFX->m_prs->ClearNullFieldStatus(nField - 1);
}
return;
case CFieldExchange::MarkForUpdate:
if (*value == '\0')
pFX->m_prs->SetNullFieldStatus(nField - 1);
else
pFX->m_prs->ClearNullFieldStatus(nField - 1);
pFX->Default(szName, value, plLength,
SQL_C_CHAR, lstrlen(value), nMaxLength);
return;
case CFieldExchange::LoadField:
{
// Get the field data
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
// Restore the status
pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
// If not NULL, restore the value and length
if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
{
value = LPTSTR(pInfo->m_pvDataCache);
*plLength = lstrlen(value);
#ifdef _UNICODE
// Must restore proxy for correct WHERE CURRENT OF operation
USES_CONVERSION;
LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
lstrcpyA(lpszData, T2A((LPCTSTR)value));
#endif // _UNICODE
}
else
{
*plLength = SQL_NULL_DATA;
}
#ifdef _DEBUG
// Buffer address must not change - ODBC's SQLBindCol depends upon this
void* pvBind;
#ifdef _UNICODE
pvBind = pFX->m_prs->m_pvFieldProxy[nField-1];
#else // !_UNICODE
pvBind = value;
#endif
if (pvBind != pInfo->m_pvBindAddress)
{
TRACE1("Error: buffer (column %u) address has changed!\n",
nField);
ASSERT(FALSE);
}
#endif // _DEBUG
}
return;
case CFieldExchange::StoreField:
AfxStoreField(*pFX->m_prs, nField, value);
return;
case CFieldExchange::AllocCache:
{
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
pInfo->m_pvDataCache = new TCHAR[nMaxLength];
pInfo->m_nDataType = AFX_RFX_LPTSTR;
}
return;
#ifdef _DEBUG
case CFieldExchange::DumpField:
*pFX->m_pdcDump << "\n" << szName << " = " << value;
return;
#endif // _DEBUG
}
}
// Note: CString.m_pchData must not be changed. This address is registered
// with ODBC and must remain valid until the recordset is released.
void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName,
CString& value, int nMaxLength, int nColumnType, short nScale)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
ASSERT(AfxIsValidAddress(&value, sizeof(CString)));
RETCODE nRetCode;
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
nField - 1, pFX->m_nFieldType);
switch (pFX->m_nOperation)
{
default:
pFX->Default(szName, value.GetBuffer(0), plLength,
SQL_C_CHAR, value.GetLength(), nMaxLength);
value.ReleaseBuffer();
return;
case CFieldExchange::BindParam:
{
// Preallocate to nMaxLength and setup binding address
value.GetBufferSetLength(nMaxLength);
void* pvParam = value.LockBuffer(); // will be overwritten if UNICODE
#ifdef _UNICODE
// Must use proxy to translate unicode data into non-unicode param
pFX->m_prs->m_bRebindParams = TRUE;
// Allocate proxy array if necessary
if (pFX->m_prs->m_pvParamProxy == NULL)
{
pFX->m_prs->m_pvParamProxy = new void*[pFX->m_prs->m_nParams];
memset(pFX->m_prs->m_pvParamProxy, 0,
pFX->m_prs->m_nParams*sizeof(void*));
pFX->m_prs->m_nProxyParams = pFX->m_prs->m_nParams;
}
// Allocate non-unicode string to nMaxLength if necessary for SQLBindParameter
if (pFX->m_prs->m_pvParamProxy[nField-1] == NULL)
{
pvParam = new CHAR[nMaxLength+1];
pFX->m_prs->m_pvParamProxy[nField-1] = pvParam;
}
else
pvParam = pFX->m_prs->m_pvParamProxy[nField-1];
// Now fill in the data value
USES_CONVERSION;
lstrcpyA((char*)pvParam, T2A((LPCTSTR)value));
#endif // _UNICODE
*plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
SQL_NULL_DATA : SQL_NTS;
AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt, (UWORD)nField,
(SWORD)pFX->m_nFieldType, SQL_C_CHAR, (SWORD)nColumnType,
nMaxLength, nScale, pvParam, nMaxLength, plLength));
value.ReleaseBuffer();
if (nRetCode != SQL_SUCCESS)
pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
// Add the member address to the param map
pFX->m_prs->m_mapParamIndex.SetAt(&value, (void*)nField);
}
return;
#ifdef _UNICODE
case CFieldExchange::RebindParam:
*plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
SQL_NULL_DATA : SQL_NTS;
if (pFX->m_prs->m_nProxyParams != 0)
{
// Fill buffer (expected by SQLBindParameter) with new param data
USES_CONVERSION;
LPSTR lpszParam = (LPSTR)pFX->m_prs->m_pvParamProxy[nField-1];
lstrcpyA(lpszParam, T2A((LPCTSTR)value));
}
return;
#endif // _UNICODE
case CFieldExchange::BindFieldToColumn:
{
// Assumes all bound fields BEFORE unbound fields
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
UINT cbColumn = pODBCInfo->m_nPrecision;
switch (pODBCInfo->m_nSQLType)
{
default:
#ifdef _DEBUG
// Warn of possible field schema mismatch
if (afxTraceFlags & traceDatabase)
TRACE1("Warning: CString converted from SQL type %ld.\n",
pODBCInfo->m_nSQLType);
#endif // _DEBUG
// Add room for extra information like sign, decimal point, etc.
cbColumn += 10;
break;
case SQL_LONGVARCHAR:
case SQL_CHAR:
case SQL_VARCHAR:
break;
case SQL_FLOAT:
case SQL_REAL:
case SQL_DOUBLE:
// Add room for sign, decimal point and " E +XXX"
cbColumn += 10;
break;
case SQL_DECIMAL:
case SQL_NUMERIC:
// Add room for sign and decimal point
cbColumn += 2;
break;
case SQL_TIMESTAMP:
case SQL_DATE:
case SQL_TIME:
// May need extra space, i.e. "{TS mm/dd/yyyy hh:mm:ss}"
cbColumn += 10;
break;
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_BIGINT:
// Add room for sign
cbColumn += 1;
break;
}
// Constrain to user specified max length, subject to 256 byte min
if (cbColumn > (UINT)nMaxLength || cbColumn < 256)
cbColumn = nMaxLength;
// Set up binding addres
void* pvData;
value.GetBufferSetLength(cbColumn+1);
pvData = value.LockBuffer(); // will be overwritten if UNICODE
#ifdef _UNICODE
// Allocate proxy array if necessary
if (pFX->m_prs->m_pvFieldProxy == NULL)
{
pFX->m_prs->m_pvFieldProxy = new void*[pFX->m_prs->m_nFields];
memset(pFX->m_prs->m_pvFieldProxy, 0,
pFX->m_prs->m_nFields*sizeof(void*));
pFX->m_prs->m_nProxyFields = pFX->m_prs->m_nFields;
}
// Allocate non-unicode string for SQLBindCol (not necessary on Requery)
if (pFX->m_prs->m_pvFieldProxy[nField-1] == NULL)
pFX->m_prs->m_pvFieldProxy[nField-1] = new CHAR[cbColumn+2];
pvData = pFX->m_prs->m_pvFieldProxy[nField-1];
#endif // _UNICODE
AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
SQL_C_CHAR, pvData, cbColumn+1, plLength));
value.ReleaseBuffer();
if (!pFX->m_prs->Check(nRetCode))
pFX->m_prs->ThrowDBException(nRetCode);
// Add the member address to the field map
pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
}
return;
#ifdef _UNICODE
case CFieldExchange::BindFieldForUpdate:
if (pFX->m_prs->m_nProxyFields != 0)
{
// Fill buffer (expected by SQLSetPos) with new field data
USES_CONVERSION;
LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
lstrcpyA(lpszData, T2A((LPCTSTR)value));
pFX->Default(szName, (void *)lpszData, plLength, SQL_C_CHAR,
value.GetLength(), nMaxLength);
}
return;
#endif // _UNICODE
case CFieldExchange::Fixup:
if (*plLength == SQL_NULL_DATA)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value.GetBufferSetLength(0);
value.ReleaseBuffer();
}
else
{
#ifdef _UNICODE
// Copy value out of the proxy
value = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
#endif
LPTSTR lpsz = value.GetBuffer(0);
if (pFX->m_prs->m_pDatabase->m_bStripTrailingSpaces)
{
// find first trailing space
LPTSTR lpszFirstTrailing = NULL;
while (*lpsz != '\0')
{
if (*lpsz != ' ')
lpszFirstTrailing = NULL;
else
{
if (lpszFirstTrailing == NULL)
lpszFirstTrailing = lpsz;
}
lpsz = _tcsinc(lpsz);
}
// truncate
if (lpszFirstTrailing != NULL)
*lpszFirstTrailing = '\0';
}
value.ReleaseBuffer();
*plLength = value.GetLength();
}
return;
case CFieldExchange::SetFieldNull:
if ((pFX->m_pvField == NULL &&
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
pFX->m_pvField == &value)
{
if (pFX->m_bField)
{
// Mark fields null
pFX->m_prs->SetNullFieldStatus(nField - 1);
// Set string 0 length
value.GetBufferSetLength(0);
value.ReleaseBuffer();
*plLength = SQL_NULL_DATA;
}
else
{
pFX->m_prs->ClearNullFieldStatus(nField - 1);
*plLength = SQL_NTS;
}
#ifdef _DEBUG
pFX->m_nFieldFound = nField;
#endif
}
return;
#ifdef _UNICODE
case CFieldExchange::NameValue:
if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
{
*pFX->m_pstr += szName;
*pFX->m_pstr += '=';
}
// Fall through
case CFieldExchange::Value:
if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
{
// Get the field data
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -