分享
 
 
 

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

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

作者:张修勇 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中下在一个免费的版本。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有