BOOL CBCGPODBCGridCtrl::GetTableList (CStringList& lstTable) { lstTable.RemoveAll (); if (m_pDataBase == NULL) { ASSERT (FALSE); return FALSE; } ASSERT_VALID (m_pDataBase); try { if (!m_pDataBase->IsOpen ()) { ASSERT (FALSE); return FALSE; } HSTMT hStmt; SQLRETURN rc = ::SQLAllocStmt(m_pDataBase->m_hdbc, &hStmt); if (!m_pDataBase->Check (rc)) { return FALSE; } #if _MSC_VER >= 1300 #ifdef UNICODE #define __BCGP_SQLCHAR SQLWCHAR #else #define __BCGP_SQLCHAR SQLCHAR #endif #else #define __BCGP_SQLCHAR SQLCHAR #endif rc = ::SQLTables (hStmt, NULL,SQL_NTS, NULL,SQL_NTS, NULL,SQL_NTS, (__BCGP_SQLCHAR*) _T("'TABLE'"), SQL_NTS); if (!m_pDataBase->Check (rc)) { AfxThrowDBException (rc, m_pDataBase, hStmt); } while ((rc = ::SQLFetch (hStmt)) != SQL_NO_DATA_FOUND) { if (!m_pDataBase->Check (rc)) { AfxThrowDBException (rc, m_pDataBase, hStmt); } UCHAR szName [256]; #if _MSC_VER < 1300 SDWORD cbName; #else SQLLEN cbName; #endif rc = ::SQLGetData (hStmt, 3, SQL_C_CHAR, szName, 256, &cbName); if (!m_pDataBase->Check (rc)) { AfxThrowDBException (rc, m_pDataBase, hStmt); } #ifdef _UNICODE lstTable.AddTail(CString(szName)); #else lstTable.AddTail ((LPCTSTR)szName); #endif } ::SQLFreeStmt (hStmt, SQL_CLOSE); } catch (CDBException* pEx) { OnODBCException (pEx); pEx->Delete (); return FALSE; } return TRUE; }
void CBCGPODBCGridCtrl::OnItemChanged (CBCGPGridItem* pItem, int nRow, int nColumn) { ASSERT_VALID (this); if (m_pRecordSet == NULL) { ASSERT (FALSE); return; } try { ASSERT_VALID (pItem); ASSERT_VALID (m_pRecordSet); CBCGPGridRow* pRow = pItem->GetParentRow (); if (pRow == NULL) { return; } ASSERT_VALID (pRow); CString strTable = m_pRecordSet->GetTableName (); RETCODE nRetCode; SQLUSMALLINT RowStatusArray[10]; SQLHSTMT hstmtU; AFX_SQL_SYNC (::SQLAllocStmt (m_pDataBase->m_hdbc, &hstmtU)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC (::SQLSetStmtAttr (hstmtU, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_LOCK, 0)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC (::SQLSetStmtAttr (hstmtU, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC (::SQLSetStmtAttr (hstmtU, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC (::SQLSetStmtAttr (hstmtU, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } _variant_t vtItemValue = pItem->GetValue (); TCHAR szFieldBuffer[5000]; SQLSMALLINT cbBoolVal; tagTIMESTAMP_STRUCT datetime; SQLSMALLINT dataFormatShort; SQLINTEGER dataFormatLong; TCHAR dataFormatChar; SQLUSMALLINT dataFormatUShort; SQLUINTEGER dataFormatULong; SQLREAL dataFormatFloat; SQLDOUBLE dataFormatDouble; #ifdef _WIN64 SQLLEN nFieldLenOrInd; SQLLEN lenColDataTypeInd; #else SQLINTEGER nFieldLenOrInd; SQLINTEGER lenColDataTypeInd; #endif switch (vtItemValue.vt) { case VT_BSTR: { CString strVal = (LPCTSTR) (_bstr_t) pItem->GetValue (); BuildURL (pItem, strVal); AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_CHAR, szFieldBuffer, strVal.GetLength (), &nFieldLenOrInd)); } break; case VT_BOOL: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_BIT, &cbBoolVal, 0, 0)); } break; case VT_DATE: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_TIMESTAMP, &datetime, sizeof (datetime), NULL)); } break; case VT_I2: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_SSHORT, &dataFormatShort, 0, &lenColDataTypeInd )); } break; case VT_I4: case VT_INT: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_SLONG, &dataFormatLong, 0, &lenColDataTypeInd )); } break; case VT_UI1: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_BIT, &dataFormatChar, 0, &lenColDataTypeInd )); } break; case VT_UI2: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_USHORT, &dataFormatUShort, 0, &lenColDataTypeInd )); } break; case VT_UINT: case VT_UI4: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_ULONG, &dataFormatULong, 0, &lenColDataTypeInd )); } break; case VT_R4: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_FLOAT, &dataFormatFloat, 0, &lenColDataTypeInd )); } break; case VT_R8: { AFX_SQL_SYNC (::SQLBindCol (hstmtU, (unsigned short)(nColumn+1), SQL_C_DOUBLE, &dataFormatDouble, 0, &lenColDataTypeInd )); } break; default: return; }; if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } CString strSQL = m_pRecordSet->GetSQL (); #ifdef _UNICODE #if _MSC_VER >= 1300 AFX_SQL_SYNC (::SQLExecDirect (hstmtU, (SQLWCHAR*)(LPCTSTR)strSQL, SQL_NTS)); #else AFX_SQL_SYNC (::SQLExecDirect (hstmtU, (UCHAR*)(LPCTSTR)strSQL, SQL_NTS)); #endif #else AFX_SQL_SYNC (::SQLExecDirect (hstmtU, (SQLCHAR*)(LPCTSTR)strSQL, SQL_NTS)); #endif if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC (::SQLFetchScroll (hstmtU, SQL_FETCH_ABSOLUTE, nRow+1)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } switch (vtItemValue.vt) { case VT_BSTR: { CString strVal = (LPCTSTR) (_bstr_t) pItem->GetValue (); BuildURL (pItem, strVal); nFieldLenOrInd = strVal.GetLength (); lstrcpy (szFieldBuffer, (LPCTSTR)strVal);; } break; case VT_DATE: { COleDateTime oleDate = (DATE) vtItemValue; datetime.day = (unsigned short)oleDate.GetDay (); datetime.month = (unsigned short)oleDate.GetMonth (); datetime.year = (unsigned short)oleDate.GetYear (); datetime.hour = (unsigned short)oleDate.GetHour (); datetime.minute = (unsigned short)oleDate.GetMinute (); datetime.second = (unsigned short)oleDate.GetSecond (); } break; case VT_BOOL: cbBoolVal = (bool) vtItemValue; break; case VT_I2: dataFormatShort = (short) vtItemValue; break; case VT_I4: case VT_INT: dataFormatLong = (long) vtItemValue; break; case VT_UI1: dataFormatChar = (TCHAR)(BYTE)vtItemValue; break; case VT_UI2: dataFormatUShort = vtItemValue.uiVal; break; case VT_UINT: case VT_UI4: dataFormatULong = vtItemValue.ulVal; break; case VT_R4: dataFormatFloat = (float) vtItemValue; break; case VT_R8: dataFormatDouble = (double) vtItemValue; break; default: return; }; AFX_SQL_SYNC (::SQLSetPos (hstmtU, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } AFX_SQL_SYNC(::SQLCloseCursor(hstmtU)); if (!m_pDataBase->Check (nRetCode)) { AfxThrowDBException (nRetCode, m_pDataBase, hstmtU); } } catch (CDBException* pEx) { OnODBCException (pEx); pEx->Delete (); OnItemUpdateFailed (); } }
void CCurRecordset::AllocAndCacheFieldInfo() { m_nResultCols = -1; ASSERT(GetODBCFieldCount() < 0); if (m_rgODBCFieldInfos != NULL) { delete[] m_rgODBCFieldInfos; m_rgODBCFieldInfos = NULL; } RETCODE nRetCode; SWORD nActualLen; // Cache the number of result columns. AFX_ODBC_CALL(::SQLNumResultCols(m_hstmt, &m_nResultCols)); if (!Check(nRetCode)) { TRACE(_T("Error: Can't get field info.\n")); AfxThrowDBException(nRetCode, m_pDatabase, m_hstmt); } // If there are no fields, quit now if (m_nResultCols == 0) return; // Allocate buffer and get the ODBC meta data. m_rgODBCFieldInfos = new CODBCFieldInfo[m_nResultCols]; LPSTR lpszFieldName; #ifdef _UNICODE // Need proxy to temporarily store non-UNICODE name. lpszFieldName = new char[MAX_FNAME_LEN + 1]; #endif // Get the field info for each field. for (WORD n = 1; n <= GetODBCFieldCount(); n++) { #ifndef _UNICODE // Reset the buffer to point to next element. lpszFieldName = m_rgODBCFieldInfos[n - 1].m_strName.GetBuffer(MAX_FNAME_LEN + 1); #endif AFX_ODBC_CALL(::SQLDescribeCol(m_hstmt, n, (UCHAR*)lpszFieldName, MAX_FNAME_LEN, &nActualLen, &m_rgODBCFieldInfos[n - 1].m_nSQLType, &m_rgODBCFieldInfos[n - 1].m_nPrecision, &m_rgODBCFieldInfos[n - 1].m_nScale, &m_rgODBCFieldInfos[n - 1].m_nNullability)); #ifndef _UNICODE m_rgODBCFieldInfos[n - 1].m_strName.ReleaseBuffer(nActualLen); #else // Copy the proxy data to correct element. m_rgODBCFieldInfos[n - 1].m_strName = lpszFieldName; #endif if (!Check(nRetCode)) { TRACE1("Error: ODBC failure getting field #%d info.\n", n); AfxThrowDBException(nRetCode, m_pDatabase, m_hstmt); } } #ifdef _UNICODE delete[] lpszFieldName; #endif }