AppBuilder中进行直接ODBC API数据库调用访问的基本方法!

    技术2022-05-11  127

    作者:张修勇  AppBuilder的网址:http://www.ucancode.com 第一章:如何为你的开发系统配置DSN: (一)、打开Windows的控制面板。选择ODBC Data Sources图标,双击打开此图标内容,此时出现ODBC Data Source Administrator对话框。 (2)、在对话框中选择User DSN然后你可以选择<添加>按钮来新增一个DSN. 第二章:如何利用ODBC API在VC下面直接编写基于数据库的程序: ODBC数据库编程 一、 一般步骤: 分配环境 应用系统在调用任何ODBC函数之前,首先必须初始化ODBC,并建立一个环境。 ODBC用该环境监视应用系统已经建立的数据库连接。每个应用系统只建立一个 环境是很有必要的,因为不管有多少连接都可以在一个环境中建立。完成这一分 配过程的ODBC函数SQLAllocEnv在下一小节描述。 SQLAllocEnv SQLAllocEnv为环境句柄分配内存,并初始化应用系统使用的ODBC调用层接口。 应用系统在调用任何其他ODBC函数之前必须调用SQLAllocEnv。 以下是SQLAllocEnv的语法: RETCODE SQLAllocEnv(phenv) SQLAllocEnv的参数如下表所示,其返回码是SQL-ERROR。因为调用SQLError 时无有效句柄,所以该函数没有SQLSTATE返回码; //分配环境句柄 SQLRETURN m_retcode; if( m_henv != SQL_NULL_HENV ) return FALSE; if (SQL_SUCCESS == (m_retcode = SQLAllocEnv( &m_henv ))) { //创建新的DSN CreateDSN(IDS_HOME_DSNNAME,IDS_HOME_DBFILENAME); //分配连接句柄 if (SQL_SUCCESS == (m_retcode = SQLAllocConnect( m_henv, &m_hdbc ))) { // 连接数据源 if (SQL_SUCCESS == (m_retcode = SQLConnect( m_hdbc, (UCHAR *)((LPCTSTR)m_strDSN), SQL_NTS, NULL, 0, NULL, 0 ))) { m_bConnected = TRUE; } } } 分配连接句柄 就象应用系统的环境由环境句柄代表一样,连接句柄代表应用系统与数据源 之间的连接。对于应用系统所要连接的每一个数据源而言,都必须分配一个连接 句柄。例如,如果需要同时与dBase和BTrieve的数据源连接,必须分配两个连接 句柄。下一小节描述函数SQLAllocConnect. SQLAllocConnect在henv标识的环境里为连接句柄分配内存。以下是 SQLAllocConnect的语法: RETCODE SQLAllocConnect(henv,phdbc) SQLAllocConnect 的参数如下表所示,其返回码是: SQL-SUCCESS SQL-SUCCESS-WITH-INFO SQL-ERROR SQL-INVALID-HANDLE SQLSTATE的返回码是: 01000 S1000 S1001 S1009 利用核心函数与数据源连接 尽管有很多ODBC函数可以建立连接,但在核心API层却只有一种,即函数 SQLConnect。它提供简单、有效的方法与数据源的连接。所有驱动程序都支持 SQLConnect,所以它是最具有互用性的解决方案。下面是SQLConnect的描述。 SQLConnect加载一个数据库驱动程序,并建立一个与数据源的连接。该连接 句柄确定所有连接信息(包括它的状态,事务状态和错误信息)的存储位置。 SQLConnect的语法如下: RETCODE SQLConnect(hdbc,szDSN,cbDSN,szUID,cbUID,szAuthStr,cbAuthAtr) SQLConnectde的返回码是: SQL-SUCCESS SQL-SUCCESS-WITH-INFO SQL-ERROR SQL-INVALID-NUMBER 与数据源断开 应用系统一旦使用完成一个数据源连接,便应与之断开。连接是十分昂贵 的资源,因为很多DBMS对同时连接的每一个许可人员或用户都是收费的。当 连接完成时,应当把它返回,以便其它用户能注册进入该系统。下面描述的ODBC 函数SQLDisconnect处理这一操作过程。 SQLDisconnect关闭与指定的连接句柄相关的数据源连接。SQLDisconnect 的语法如下: RETCODESQLDisconnect(hdbc) SQLDisconnect的返回码是: SQL-SUCCESS SQL-SUCCESS-WITH-INFO SQL-ERROR SQL-INVALID-HANDLE 如果数据源连接成功的话,就可以继续下一步; CString strSQLString; RETCODE ReturnCode; SQLHSTMThstmt; if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT,theApp.m_hdbc,&hstmt)) return; strSQLString.Format( "SELECT " "NID," "ARIQI," "NJINE," "ASHUOMING," "ALAIYUAN," "ACUNZHE," "AYONGTU," "AXIAOFEI," "ABEIZHU" " FROM HHZhiChu " " WHERE NID=%u", nID); if (SQL_SUCCESS == (ReturnCode = SQLExecDirect(hstmt,(UCHAR*)((LPCTSTR)strSQLString),SQL_NTS))) { SQLBindCol(hstmt,1,SQL_C_SLONG,&dbdata.m_Nid,0,&cb); SQLBindCol(hstmt,2,SQL_C_TIMESTAMP,&dbdata.m_Ariqi,0,&cb); SQLBindCol(hstmt,3,SQL_C_DOUBLE,&dbdata.m_Njine,0,&cb); SQLBindCol(hstmt,4,SQL_C_CHAR,dbdata.m_Ashuoming,HHZhiChu_aShuoMing_SIZE,&cb); SQLBindCol(hstmt,5,SQL_C_CHAR,dbdata.m_Alaiyuan,HHZhiChu_aLaiYuan_SIZE,&cb); SQLBindCol(hstmt,6,SQL_C_CHAR,dbdata.m_Acunzhe,HHZhiChu_aCunZhe_SIZE,&cb); SQLBindCol(hstmt,7,SQL_C_CHAR,dbdata.m_Ayongtu,HHZhiChu_aYongTu_SIZE,&cb); SQLBindCol(hstmt,8,SQL_C_CHAR,dbdata.m_Axiaofei,HHZhiChu_aXiaoFei_SIZE,&cb); SQLBindCol(hstmt,9,SQL_C_CHAR,dbdata.m_Abeizhu,HHZhiChu_aBeiZhu_SIZE,&cb); if (SQL_SUCCESS == (ReturnCode = SQLFetch(hstmt))) { //读数据成功,可一对数据进行处理了。 } } ::SQLFreeHandle(SQL_HANDLE_STMT,hstmt); 程序完了后要关闭数据库, //断开连接 if (m_bConnected) { SQLDisconnect(m_hdbc); SQLFreeHandle(SQL_HANDLE_DBC,m_hdbc); m_hdbc = NULL; } //删除DSN if (FoundDSNName(IDS_HOME_DSNNAME)) DeleteDSN(IDS_HOME_DSNNAME); //删除环境句柄 if (m_henv) { SQLFreeHandle(SQL_HANDLE_ENV,m_henv); m_henv = NULL; } 二、 针对数据库的操作 以下的方法只对ACCESS数据库有效, 1、 生成数据库 CString strFileName="c:/1.mdb"; CString strDriver; char szFileName[100+_MAX_PATH]; strDriver = "Microsoft Access Driver (*.mdb)/0"; sprintf(szFileName,"CREATE_DB=%s General/0/0",strFileName); SQLConfigDataSource(NULL,ODBC_ADD_DSN,strDriver,szFileName); 2、 压缩数据库 BOOL SuperDatabase::Compaction(CString strSourName, CString strDestName) { if (strSourName.IsEmpty()) return FALSE; if (strDestName.IsEmpty()) strDestName = strSourName; char szCommand[100+_MAX_PATH]; int j; CString strDriver; strDriver = "Microsoft Access Driver (*.mdb)/0"; j = sprintf(szCommand,"COMPACT_DB=%s %s General/0/0",strSourName,strDestName); return SQLConfigDataSource(NULL,ODBC_ADD_DSN,strDriver,szCommand); } 3、 取得数据库的名称: 如果已经打开了一个数据源,可以通过数据源来取得当前的数据库的名称; CString SuperDatabase::GetDatabaseName() { ASSERT(m_hdbc != SQL_NULL_HDBC); char szName[MAX_TNAME_LEN]; SWORD nResult; SQLGetInfo(m_hdbc, SQL_DATABASE_NAME, szName, MAX_TNAME_LEN, &nResult); return szName; } 三、 针对数据源的操作: 1、 增加数据源 BOOL SuperDatabase::CreateDSN(CString strDriver, CString strFileName,CString strDSN, CString strUserID, CString strPWD) { char szAttr[100+_MAX_PATH]; int j; if (strDriver.IsEmpty()) strDriver = "Microsoft Access Driver (*.mdb)/0"; j = sprintf(szAttr,"DSN=%s/0",strDSN); j++; j = sprintf(szAttr+j,"DBQ=%s/0/0 ",strFileName); return SQLConfigDataSource(NULL,ODBC_ADD_DSN,strDriver,szAttr); } 2、 删除数据源 void SuperDatabase::RemoveDSN(CString strDSN) { char szDSN[255]; sprintf(szDSN,"DSN=%s/0/0",strDSN); BOOL bIsSuccess = SQLConfigDataSource(NULL,ODBC_REMOVE_DSN,"Microsoft Access Driver (*.mdb)/0",szDSN); } 3、 取得系统已有得DSN SWORD nDataSourceNameLength; //DSN str length SWORD nSourceDescriptionLength; //Driver Description str length char szSourceDescription[MAXBUFLEN+1]; //Driver Description string SQLRETURN nResult; //Return Code SWORD nDirection=SQL_FETCH_FIRST; if ((nResult = SQLDataSources(m_henv, nDirection, (UCHAR *)((LPCTSTR)strDataSourceName), MAXBUFLEN, &nDataSourceNameLength, (UCHAR *)szSourceDescription, MAXBUFLEN, &nSourceDescriptionLength)) != SQL_NO_DATA && nResult != SQL_ERROR) { nDirection=SQL_FETCH_NEXT; // szSourceDescription为DSN 的描述,可以在这里取来用; } 四、 针对表的操作: 1、 取得表名: void SuperDatabase::GetTable(CStringList &tableList) { ASSERT(m_bIsConnect); if (!m_bIsConnect) return; SQLHSTMT hstmt = NULL; if (SQL_SUCCESS == ::SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &hstmt)) { if (SQL_SUCCESS == ::SQLTables(hstmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) { SDWORD cb; char szTable[255]; char szTableType[255]; ::SQLBindCol(hstmt, 3, SQL_C_CHAR, szTable, 255, &cb); ::SQLBindCol(hstmt, 4, SQL_C_CHAR, szTableType, 255, &cb); while (SQL_SUCCESS == ::SQLFetch(hstmt)) { if (0 == strcmp(szTableType, "TABLE"))//TABLE表示表,VIEW表示查询 { tableList.AddTail(szTable); } } } } ::SQLFreeHandle(SQL_HANDLE_STMT, hstmt); hstmt = NULL; } 2、 创建表:可以用SQL语句生成表,使用的命令为:"CREATE TABLE": CREATE TABLE table (field1 type [(size)] [NOT NULL] [index1] [, field2 type [(size)] [NOT NULL] [index2] [, ...]] [, CONSTRAINT multifieldindex [, ...]]) 其中,各类型type如下: 数据类型 Type参数 整型 SHORT 长整型 INTEGER 单精度 FLOAT 双精度 DOUBLE 字符串 TEXT 日期 DATETIME 是/否 BIT 货币 CURRENCY 系统自动编号 COUNTER 五、 对列的操作: 1、 取得SQL语句中的列数: int SuperRecordSet::GetColCount() { SWORD swColCount; if (m_hstmt == NULL) return -1; if (SQL_SUCCESS == ::SQLNumResultCols(m_hstmt,&swColCount)) return swColCount; else return -1; } 七、数据的读取 1、列绑定: CString strSQLString; RETCODE ReturnCode; SQLHSTMT hstmt; if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT,theApp.m_hdbc,&hstmt)) return; FF_DB_HHZHICHU_SET_FIELDS dbdata; SDWORD cb1; SDWORD cb2; SDWORD cb3; SDWORD cb4; SDWORD cb5; SDWORD cb6; SDWORD cb7; SDWORD cb8; SDWORD cb9; // Build the SQL Statement strSQLString.Format( "SELECT " "NID," "ARIQI," "NJINE," "ASHUOMING," "ALAIYUAN," "ACUNZHE," "AYONGTU," "AXIAOFEI," "ABEIZHU" " FROM HHZhiChu " " WHERE NID=%u", nID); if (SQL_SUCCESS == (ReturnCode = SQLExecDirect(hstmt,(UCHAR*)((LPCTSTR)strSQLString),SQL_NTS))) { SQLBindCol(hstmt,1,SQL_C_SLONG,&dbdata.m_Nid,0,&cb1); SQLBindCol(hstmt,2,SQL_C_TIMESTAMP,&dbdata.m_Ariqi,0,&cb2); SQLBindCol(hstmt,3,SQL_C_DOUBLE,&dbdata.m_Njine,0,&cb3); SQLBindCol(hstmt,4,SQL_C_CHAR,dbdata.m_Ashuoming,HHZhiChu_aShuoMing_SIZE,&cb4); SQLBindCol(hstmt,5,SQL_C_CHAR,dbdata.m_Alaiyuan,HHZhiChu_aLaiYuan_SIZE,&cb5); SQLBindCol(hstmt,6,SQL_C_CHAR,dbdata.m_Acunzhe,HHZhiChu_aCunZhe_SIZE,&cb6); SQLBindCol(hstmt,7,SQL_C_CHAR,dbdata.m_Ayongtu,HHZhiChu_aYongTu_SIZE,&cb7); SQLBindCol(hstmt,8,SQL_C_CHAR,dbdata.m_Axiaofei,HHZhiChu_aXiaoFei_SIZE,&cb8); SQLBindCol(hstmt,9,SQL_C_CHAR,dbdata.m_Abeizhu,HHZhiChu_aBeiZhu_SIZE,&cb9); // Fetch and store... if (SQL_SUCCESS == (ReturnCode = SQLFetch(hstmt))) { m_Record.m_Nid = dbdata.m_Nid; m_Record.m_Ariqi.SetDateTime(dbdata.m_Ariqi.year, dbdata.m_Ariqi.month, dbdata.m_Ariqi.day, dbdata.m_Ariqi.hour, dbdata.m_Ariqi.minute, dbdata.m_Ariqi.second); m_Record.m_Njine = dbdata.m_Njine; m_Record.m_Ashuoming = dbdata.m_Ashuoming; m_Record.m_Alaiyuan = dbdata.m_Alaiyuan; m_Record.m_Acunzhe = dbdata.m_Acunzhe; m_Record.m_Ayongtu = dbdata.m_Ayongtu; m_Record.m_Axiaofei = dbdata.m_Axiaofei; m_Record.m_Abeizhu = dbdata.m_Abeizhu; } } ::SQLFreeHandle(SQL_HANDLE_STMT,hstmt); 其中,如果cb1、cb2、cb3、cb4、cb5、cb6、cb7、cb8、cb9是接受返回的数据的大小的,如果他们的值等于SQL_NULL_DATA,那么表示此记录的这个字段的值为空。 2、块绑定 CStuffbasicdataQry::CStuffbasicdataQry(CODBCDatabase* pDB) : m_nRowSetSize(1000), m_pDatabase(pDB) { m_hstmt = SQL_NULL_HSTMT; RETCODE ReturnCode = SQLAllocHandle(SQL_HANDLE_STMT, m_pDatabase->GetHDBC(), &m_hstmt); if (ReturnCode != SQL_SUCCESS) TRACE("Unable to allocate Statement Handle in CTtttempSet/n"); } CStuffbasicdataQry::~CStuffbasicdataQry() { Reset(); if (m_hstmt) SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt); } void CStuffbasicdataQry::Reset() { if (m_hstmt) SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt); for (int i = 0; i < m_aData.GetSize(); i++) delete m_aData.GetAt(i); m_aData.RemoveAll(); } int CStuffbasicdataQry::Load() { CString strSQLString; //RETCODE ReturnCode; UDWORD RowsFetched; UWORD *pRowStatus; pFF_DB_STUFFBASICDATAQRY_FIELDS pHostData; ASSERT(m_nRowSetSize > 0); pRowStatus = new UWORD[m_nRowSetSize]; ASSERT(pRowStatus); pHostData = new FF_DB_STUFFBASICDATAQRY_FIELDS[m_nRowSetSize]; ASSERT(pHostData); SQLSetStmtOption(m_hstmt,SQL_BIND_TYPE,sizeof(FF_DB_STUFFBASICDATAQRY_FIELDS)); SQLSetStmtOption(m_hstmt,SQL_CONCURRENCY,SQL_CONCUR_READ_ONLY); SQLSetStmtOption(m_hstmt,SQL_CURSOR_TYPE,SQL_CURSOR_KEYSET_DRIVEN); SQLSetStmtOption(m_hstmt,SQL_ROWSET_SIZE,m_nRowSetSize); strSQLString.Format( "SELECT * " " FROM STUFFBASICDATA"); if (SQL_SUCCESS == SQLExecDirect(m_hstmt,(UCHAR*)((LPCTSTR)strSQLString),SQL_NTS)) { SQLBindCol(m_hstmt,1,SQL_C_CHAR,pHostData[0].m_aStuffID,StuffbasicdataQry_aStuffID_SIZE,&pHostData[0].m_aStuffIDInd); SQLBindCol(m_hstmt,2,SQL_C_CHAR,pHostData[0].m_aNameCN,StuffbasicdataQry_aNameCN_SIZE,&pHostData[0].m_aNameCNInd); SQLBindCol(m_hstmt,3,SQL_C_CHAR,pHostData[0].m_aNameEN,StuffbasicdataQry_aNameEN_SIZE,&pHostData[0].m_aNameENInd); SQLBindCol(m_hstmt,4,SQL_C_CHAR,pHostData[0].m_aEducation,StuffbasicdataQry_aEducation_SIZE,&pHostData[0].m_aEducationInd); SQLBindCol(m_hstmt,5,SQL_C_CHAR,pHostData[0].m_aGender,StuffbasicdataQry_aGender_SIZE,&pHostData[0].m_aGenderInd); SQLBindCol(m_hstmt,6,SQL_C_TIMESTAMP,&pHostData[0].m_dWorkDate,0,&pHostData[0].m_dWorkDateInd); SQLBindCol(m_hstmt,7,SQL_C_CHAR,pHostData[0].m_aDepartment,StuffbasicdataQry_aDepartment_SIZE,&pHostData[0].m_aDepartmentInd); SQLBindCol(m_hstmt,8,SQL_C_CHAR,pHostData[0].m_aBusiness,StuffbasicdataQry_aBusiness_SIZE,&pHostData[0].m_aBusinessInd); SQLBindCol(m_hstmt,9,SQL_C_CHAR,pHostData[0].m_aBusinessLevel,StuffbasicdataQry_aBusinessLevel_SIZE,&pHostData[0].m_aBusinessLevelInd); SQLBindCol(m_hstmt,10,SQL_C_CHAR,pHostData[0].m_aWorkType,StuffbasicdataQry_aWorkType_SIZE,&pHostData[0].m_aWorkTypeInd); SQLBindCol(m_hstmt,11,SQL_C_TIMESTAMP,&pHostData[0].m_dLeaveWorkDate,0,&pHostData[0].m_dLeaveWorkDateInd); SQLBindCol(m_hstmt,12,SQL_C_CHAR,pHostData[0].m_aEnageType,StuffbasicdataQry_aEnageType_SIZE,&pHostData[0].m_aEnageTypeInd); SQLBindCol(m_hstmt,13,SQL_C_TIMESTAMP,&pHostData[0].m_dCreateDocDate,0,&pHostData[0].m_dCreateDocDateInd); while (SQL_SUCCESS == SQLExtendedFetch(m_hstmt,SQL_FETCH_NEXT,1,&RowsFetched,pRowStatus)) { for (UINT Count = 0; Count < RowsFetched; Count++) { if (pRowStatus[Count] != SQL_ROW_DELETED && pRowStatus[Count] != SQL_ROW_ERROR ) { pDB_STUFFBASICDATAQRY_FIELDS pData = new DB_STUFFBASICDATAQRY_FIELDS(); ASSERT(pData); if (pHostData[Count].m_aStuffIDInd == SQL_NULL_DATA) pData->m_aStuffID = ""; else pData->m_aStuffID = pHostData[Count].m_aStuffID; if (pHostData[Count].m_aNameCNInd == SQL_NULL_DATA) pData->m_aNameCN = ""; else pData->m_aNameCN = pHostData[Count].m_aNameCN; if (pHostData[Count].m_aNameENInd == SQL_NULL_DATA) pData->m_aNameEN = ""; else pData->m_aNameEN = pHostData[Count].m_aNameEN; if (pHostData[Count].m_aEducationInd == SQL_NULL_DATA) pData->m_aEducation = ""; else pData->m_aEducation = pHostData[Count].m_aEducation; if (pHostData[Count].m_aGenderInd == SQL_NULL_DATA) pData->m_aGender = ""; else pData->m_aGender = pHostData[Count].m_aGender; pData->m_dWorkDate.SetDateTime(pHostData[Count].m_dWorkDate.year, pHostData[Count].m_dWorkDate.month, pHostData[Count].m_dWorkDate.day, pHostData[Count].m_dWorkDate.hour, pHostData[Count].m_dWorkDate.minute, pHostData[Count].m_dWorkDate.second); if (pHostData[Count].m_aDepartmentInd == SQL_NULL_DATA) pData->m_aDepartment = ""; else pData->m_aDepartment = pHostData[Count].m_aDepartment; if (pHostData[Count].m_aBusinessInd == SQL_NULL_DATA) pData->m_aBusiness = ""; else pData->m_aBusiness = pHostData[Count].m_aBusiness; if (pHostData[Count].m_aBusinessLevelInd == SQL_NULL_DATA) pData->m_aBusinessLevel = ""; else pData->m_aBusinessLevel = pHostData[Count].m_aBusinessLevel; if (pHostData[Count].m_aWorkTypeInd == SQL_NULL_DATA) pData->m_aWorkType = ""; else pData->m_aWorkType = pHostData[Count].m_aWorkType; pData->m_dLeaveWorkDate.SetDateTime(pHostData[Count].m_dLeaveWorkDate.year, pHostData[Count].m_dLeaveWorkDate.month, pHostData[Count].m_dLeaveWorkDate.day, pHostData[Count].m_dLeaveWorkDate.hour, pHostData[Count].m_dLeaveWorkDate.minute, pHostData[Count].m_dLeaveWorkDate.second); if (pHostData[Count].m_aEnageTypeInd == SQL_NULL_DATA) pData->m_aEnageType = ""; else pData->m_aEnageType = pHostData[Count].m_aEnageType; pData->m_dCreateDocDate.SetDateTime(pHostData[Count].m_dCreateDocDate.year, pHostData[Count].m_dCreateDocDate.month, pHostData[Count].m_dCreateDocDate.day, pHostData[Count].m_dCreateDocDate.hour, pHostData[Count].m_dCreateDocDate.minute, pHostData[Count].m_dCreateDocDate.second); m_aData.Add(pData); } } if (RowsFetched < (UINT)m_nRowSetSize) break; } } delete [] pRowStatus; delete [] pHostData; return m_aData.GetSize(); } 八、写数据库 1、普通方法: CString strSQL="INSERT INTO TABLE (FILE1,FILE2,FILE3) VALUES (value1,value2,value3)" long ExecuteSQL(SQLHDBC hdbc,CString strSQL) { SQLRETURN ReturnCode; SQLHSTMT m_hstmt; BOOL bReturn = FALSE; long nRowCount = 0; if (SQL_SUCCESS == (ReturnCode = ::SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&m_hstmt))) { if (SQL_SUCCESS == (ReturnCode = ::SQLExecDirect(m_hstmt, (UCHAR*)((LPCTSTR)strSQL),SQL_NTS))) { bReturn = TRUE; ::SQLRowCount(m_hstmt,&nRowCount); } } ReturnCode = ::SQLFreeHandle(SQL_HANDLE_STMT,m_hstmt); // if (!bReturn) nRowCount = 0; return nRowCount; } 注意,要把字段赋为空,字符串、日期应是NULL,可以用下面的函数修改: CString VerifySQLStr(CString strSQL) { int nLength = strSQL.GetLength(); int n1 = 0;//check ''; int n2 = 0; int m1 = 0;//check ##; int m2 = 0; for (int i = 0; i< nLength;i++) { if (strSQL[i] == 39) { n2 = i; if (n2-n1 == 1) { strSQL.Delete(n1,2); strSQL.Insert(n1,"NULL"); nLength +=2; n1 = n2; } else { n1 = n2; } } if (strSQL[i] == '#') { m2 = i; if (m2-m1 == 1) { strSQL.Delete(m1,2); strSQL.Insert(m1,"NULL"); nLength +=2; m1 = m2; } else { m1 = m2; } } } return strSQL; } 2、参数绑定: bool CCddataSet::Insert(pDB_CDDATA_SET_FIELDS pData, bool bFirstTime /* true */) { RETCODE ReturnCode; CString strSQLString; static FF_DB_CDDATA_SET_FIELDS HostData; // Prepare the statement and bind the columns once if (bFirstTime) { memset(&HostData,0,sizeof(HostData)); SQLFreeStmt(m_hstmt, SQL_CLOSE); // Close the cursor if any SQLFreeStmt(m_hstmt, SQL_RESET_PARAMS); // Reset the statement handle strSQLString.Format("INSERT INTO CDData (" "NGUANGPAN," "NWENJIAN," "NCLASS," "AWENJIAN," "NSHANGJI," "NSHUXING," "ABEIZHU )" "VALUES (" "?," // nGuangPan "?," // nWenJian "?," // nClass "?," // aWenJian "?," // nShangJi "?," // nShuXing "? )" // aBeiZhu ); // end format ReturnCode = SQLPrepare(m_hstmt, (UCHAR*)((LPCTSTR)strSQLString),SQL_NTS); if (ReturnCode != SQL_SUCCESS) { return false; } SQLBindParameter(m_hstmt,1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0,&HostData.m_Nguangpan,0,&HostData.m_NguangpanInd ); SQLBindParameter(m_hstmt, 2,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER, 0, 0,&HostData.m_Nwenjian,0, &HostData.m_NwenjianInd ); SQLBindParameter(m_hstmt,3,SQL_PARAM_INPUT, SQL_C_SLONG,SQL_INTEGER, 0, 0,&HostData.m_Nclass,0,&HostData.m_NclassInd ); SQLBindParameter(m_hstmt,4,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR, CDData_aWenJian_SIZE,0,HostData.m_Awenjian,0,&HostData.m_AwenjianInd ); SQLBindParameter(m_hstmt,5,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0, 0,&HostData.m_Nshangji, 0, &HostData.m_NshangjiInd ); SQLBindParameter(m_hstmt,6,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER, 0, 0, &HostData.m_Nshuxing, 0,&HostData.m_NshuxingInd ); SQLBindParameter(m_hstmt, 7,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR, CDData_aBeiZhu_SIZE,0, HostData.m_Abeizhu, 0,&HostData.m_AbeizhuInd ); } // Move the data to host structure and execute the statement HostData.m_Nguangpan = pData->m_Nguangpan; HostData.m_Nwenjian = pData->m_Nwenjian; HostData.m_Nclass = pData->m_Nclass; HostData.m_AwenjianInd = SQL_NTS; memcpy(HostData.m_Awenjian, pData->m_Awenjian, CDData_aWenJian_SIZE); HostData.m_Nshangji = pData->m_Nshangji; HostData.m_Nshuxing = pData->m_Nshuxing; HostData.m_AbeizhuInd = SQL_NTS; memcpy(HostData.m_Abeizhu, pData->m_Abeizhu, CDData_aBeiZhu_SIZE); ReturnCode = SQLExecute(m_hstmt); if (ReturnCode != SQL_SUCCESS) { return false; } return true; } 九、其他操作: 1、检测SQL错误: void DisplayError(SQLRETURN nResult, SWORD fHandleType, SQLHANDLE handle) { UCHAR szErrState[SQL_SQLSTATE_SIZE+1]; // SQL Error State string UCHAR szErrText[SQL_MAX_MESSAGE_LENGTH+1]; // SQL Error Text string char szBuffer[1000]; char szDispBuffer[1000]; // Display Buffer // formatted Error text Buffer SWORD wErrMsgLen; // Error message length long dwErrCode; // Native Error code int iSize; // Display Error Text size SQLRETURN nErrResult; // Return Code from SQLGetDiagRec SWORD sMsgNum = 1; SWORD fFirstRun = TRUE; szBuffer[0] = '/0'; do { // continue to bring messageboxes till all errors are displayed. // more than one message box may be reqd. as err text has fixed // string size. // initialize display buffer with the string in error text buffer strcpy(szDispBuffer, szBuffer); // call SQLGetDiagRec function with proper ODBC handles, repeatedly until // function returns SQL_NO_DATA. Concatenate all error strings // in the display buffer and display all results. while ((nErrResult = SQLGetDiagRec(fHandleType, handle, sMsgNum++, szErrState, &dwErrCode, szErrText, SQL_MAX_MESSAGE_LENGTH-1, &wErrMsgLen)) != SQL_NO_DATA) { if(nErrResult == SQL_ERROR ¦¦ nErrResult == SQL_INVALID_HANDLE) break; wsprintf(szBuffer, SQLERR_FORMAT, (LPSTR)szErrState, dwErrCode, (LPSTR)szErrText); iSize = strlen(szDispBuffer); if (iSize && (iSize+strlen(szBuffer)+1) >= 1000) break; if (iSize) strcat(szDispBuffer, "/n"); strcat(szDispBuffer, szBuffer); } // display proper ERROR or WARNING message with proper title if (nResult == SQL_SUCCESS_WITH_INFO) MessageBox(NULL, szDispBuffer, (fFirstRun? SQLWRNMSGTITLE : SQLWRNCNTDTITLE), MB_OK ¦ MB_ICONINFORMATION); else MessageBox(NULL, szDispBuffer, (fFirstRun? SQLERRMSGTITLE : SQLERRCNTDTITLE), MB_OK ¦ MB_ICONEXCLAMATION); if (fFirstRun) fFirstRun = FALSE; } while (!(nErrResult == SQL_NO_DATA ¦¦ nErrResult == SQL_ERROR ¦¦ nErrResult == SQL_INVALID_HANDLE)); } 分配和释放语句 任何与处理和传递SQL语句相关的SQL函数都要求一个有效的语句句柄作为 参数。语句句柄很象环境或连接句柄,区别之处在于它引用SQL语句或者其它 返回结果的ODBC函数。一个连接句柄可以与几个语句句柄相关连,但每一个 语句句柄只能与一个连接句柄相关连。应用系统要想分配语句句柄,只需调用 下面描述的SQLAllocStmt即可。 SQLAllocStmt为语句句柄分配内存存储区,并将此句柄与连接句柄指定的 连接联系在一起。应用系统必须先用SQLAllocStmt为SQL语句分配内存,然后 才能提供引用某一特殊语句句柄的SQL语句。 SQLAllocStmt的语法如下: RETCODE SQLAllocStmt(hdbc,phstmt) SQLAllocStmt的返回码为: SQL-SUCCESS SQL-SUCCESS-WITH-INFO SQL-INVALID-HANDLE SQL-ERROR SQLFreeStmt SQLFreeStmt完成以下动作: .停止任何与指定语句句柄相关的、当前正在处理的SQL语句; 关闭任何与指定语句句柄相关的打开光标; 舍弃所有未完成的结果。 有选择的释放与指定语句句柄相关的所有资源; SQLFreeStmt的语法为: RETCODE SQLFreeStmt(hstmt,fOption) SQLFreeStmt的返回码是: SQL-SUCCESS SQL-SUCCESS-WITH-INFO SQL-INVALID-HANDLE SQL-ERROR 最后 在我们的开发系统AppBuilder中你可以不必对上面的复杂的过程进行完整的了解,你也不必书写任何的调用代码,我们将这一切都自动为你产生,同时还和开发最终程序的界面融合在一起,一切都非常简单。为你的开发自动编写大量的代码,如果你需要看看,请到:www.ucancode.com中下在一个免费的版本。

    最新回复(0)