如何用YC++操作数据库

来源:互联网 发布:淘宝秒杀是什么意思啊 编辑:程序博客网 时间:2024/05/01 13:58

                                                            如何用YC++操作数据库

     在YC++中,可以用多种方式操作数据库。这里列举了一个采用ODBC规范进行数据库编程的例子。
     ODBC提供了很多API函数, 这些函数及其使用到的结构、宏等的声明都在头文件sqlucode.h中, 这些函数
的二进制代码则在odbc32.dll库中。
     在vc++中, 若要使用ODBC的API函数, 则需要包含sqlucode.h,并指定链接文件odbc32.lib。
     在yc++中, 编译器默认包含了头文件: YC01/include/yca.h, 查看后可发现yca.h又包头文件sqlucode.h,
由于YC++会自动链接yca.h中声明的所有库函数, 因此在yc++中,不必再包含yca.h中的头文件,也不需要再指定DLL库。

/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
运行该例需将YC++的下列几个文件拷入你的源程序所在目录:

   YC01/yxbapi.dll    C/C++编译器, 浏览器内核库
   YC01/yxbimg.dll    图象, 动画解码库
   YC01/yxbext.dll    浏览器内核交互代码库

   YC01/examples/y.mdb    数据库文件, 它是用MS Access创建的, 其中只有一个表: me

/*****************************************************************************************************************/
将下列代码存入名字任取的文件, 如: blog4a.cpp
在yc++中, 用<文件/打开或创建cpp源程序>调入blog4a.cpp, 再用 <工具/执行>运行blog4a.cpp
   或在dos中, 用 ycc blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe
在vc++中, 用 cl blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe

/*****************************************************************************************************************/

#ifndef YCC     //yc++的头文件ycansi.h中定义了YCC标识符, 而其它编译器没有定义它
#include       
#include       
#include       
//#include       
//#include       
//#include       

#pragma         comment(lib, "user32.lib")
#pragma         comment(lib, "odbc32.lib")
#endif

#define  MAX_DB_FILEDS   100       //最大字段数
#define  MAX_DB_STRLEN   1024      //字段的最大长度

struct  DBObject
{
 UDWORD       fieldlen[MAX_DB_FILEDS];
 SWORD        fSqlType[MAX_DB_FILEDS];
 SQLCHAR      FieldStr[MAX_DB_FILEDS][MAX_DB_STRLEN];
 SQLSMALLINT  fieldnum;
 SQLHENV      hEnv;
 SQLHDBC      hDBC;
 SQLHSTMT     hstmt;
 SQLCHAR      colName[MAX_DB_FILEDS][256];
};

void main()
{
    char mdb_name[] = "y.mdb";      //要被操作的数据库文件名
    char table_name[] = "me";       //要被操作的数据库表名字

    DBObject  rdb;
    if(SQLAllocEnv(&rdb.hEnv) != SQL_SUCCESS)    return;     //分配ODBC环境
    if(SQLAllocConnect(rdb.hEnv,&rdb.hDBC) != SQL_SUCCESS)   //分配连接用内存
      {
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    SQLCHAR  szConnStr[1024],constr[MAX_PATH+128];
    sprintf((char*)constr,"DBQ=%s;DRIVER={Microsoft Access Driver (*.mdb)}", mdb_name);

    //加载驱动程序,连接源
    if(SQLDriverConnect(rdb.hDBC,NULL,constr,strlen((char*)constr),szConnStr,sizeof(szConnStr),NULL,SQL_DRIVER_NOPROMPT) != SQL_SUCCESS)
      {
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    if(SQLAllocStmt(rdb.hDBC,&rdb.hstmt) != SQL_SUCCESS)  //为SQL语句分配内存
      {
 SQLDisconnect(rdb.hDBC);
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    //设置SQL语句
    SQLCHAR  szStmt[255];
    strcpy((char*)szStmt,"SELECT * FROM ");
    strcat((char*)szStmt, table_name);
    SQLExecDirect(rdb.hstmt, szStmt, SQL_NTS);  //执行ODBC语句

    SQLNumResultCols(rdb.hstmt,&rdb.fieldnum);
    rdb.fieldnum = min(rdb.fieldnum, MAX_DB_FILEDS);

    for(int ii=0; ii      {
 SQLDescribeCol(rdb.hstmt,ii+1, rdb.colName[ii], sizeof rdb.colName[ii], NULL, &rdb.fSqlType[ii], &rdb.fieldlen[ii], NULL, NULL);
 SQLBindCol(rdb.hstmt, ii+1, SQL_C_DEFAULT, rdb.FieldStr[ii], MAX_DB_STRLEN, NULL);
      }

    //print
    void print_db(DBObject *pRdb);
    print_db(&rdb);

    //exit
    SQLCloseCursor(rdb.hstmt);
    SQLFreeStmt(rdb.hstmt,SQL_CLOSE);
    SQLDisconnect(rdb.hDBC);
    SQLFreeConnect(rdb.hDBC);
    SQLFreeEnv(rdb.hEnv);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BinToChar(char *outstr, char *instr, SDWORD count)
{
    char *ostr=outstr;
    while(count--)
      {
 UCHAR uletter = (*instr & 0xF0) >> 4;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
 uletter = *instr++ & 0x0F;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
      }
    *ostr = '/0';
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void get_db_field_text(DBObject *pRdb,int Col,char *outbuff)
{
static char szdate[] = "%02u/%02u/%02u";
static char sztime[] = "%02u:%02u:%02u";
static char sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";

    char *inbuff = (char*)pRdb->FieldStr[Col];
    *outbuff = '/0';

    switch(pRdb->fSqlType[Col])
      {
 case SQL_CHAR:
 case SQL_VARCHAR:
 case SQL_LONGVARCHAR:
      strcpy(outbuff,inbuff);
      break;
 case SQL_BINARY:
 case SQL_VARBINARY:
 case SQL_LONGVARBINARY:
      strcpy(outbuff, "0x");
      BinToChar(outbuff+2, (char*)inbuff, pRdb->fieldlen[Col]);
      break;
 case SQL_TINYINT:
 case SQL_SMALLINT:
      SWORD   FAR *tmpsword;
      tmpsword = (SWORD FAR *)inbuff;
      wsprintf(outbuff, "%d", *tmpsword);
      break;
 case SQL_BIT:
      tmpsword = (SWORD FAR *)inbuff;
      strcpy(outbuff, (*tmpsword) ? "1" : "0");
      break;
 case SQL_INTEGER:
 case SQL_BIGINT:
      SDWORD  FAR *tmpsdword;
      tmpsdword = (SDWORD FAR *)inbuff;
      wsprintf(outbuff, "%ld", *tmpsdword);
      break;
 case SQL_FLOAT:
 case SQL_DOUBLE:
      SDOUBLE FAR *tmpsdouble;
      tmpsdouble = (SDOUBLE FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsdouble);
      break;
 case SQL_REAL:
      SFLOAT  FAR *tmpsfloat;
      tmpsfloat = (SFLOAT FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsfloat);
      break;
 case SQL_DECIMAL:
 case SQL_NUMERIC:
      strcpy(outbuff, inbuff);
      break;
 case SQL_DATE:
      DATE_STRUCT FAR *tmpdate;
      tmpdate = (DATE_STRUCT FAR *)inbuff;
      wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
      break;
 case SQL_TIME:
      TIME_STRUCT FAR *tmptime;
      tmptime= (TIME_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
      break;
 case SQL_TIMESTAMP:
      TIMESTAMP_STRUCT FAR *tmptimestmp;
      tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month, tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,tmptimestmp->second, tmptimestmp->fraction);
      break;
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void print_db(DBObject *pRdb)
{
    printf("/n");
    for(int col=0; colfieldnum; col++)
      {
 printf((char*)pRdb->colName[col]);
 printf("/t");
      }
    for(;;)
      {
 if(SQLFetch(pRdb->hstmt) != SQL_SUCCESS)  break;

 printf("/n");
 for(int col=0; colfieldnum; col++)
   {
     char des_buf[MAX_DB_STRLEN];
     get_db_field_text(pRdb,col,des_buf);
     printf(des_buf);
     printf("/t");
   }
      }
    printf("/n");




                                                            如何用YC++操作数据库

     在YC++中,可以用多种方式操作数据库。这里列举了一个采用ODBC规范进行数据库编程的例子。
     ODBC提供了很多API函数, 这些函数及其使用到的结构、宏等的声明都在头文件sqlucode.h中, 这些函数
的二进制代码则在odbc32.dll库中。
     在vc++中, 若要使用ODBC的API函数, 则需要包含sqlucode.h,并指定链接文件odbc32.lib。
     在yc++中, 编译器默认包含了头文件: YC01/include/yca.h, 查看后可发现yca.h又包头文件sqlucode.h,
由于YC++会自动链接yca.h中声明的所有库函数, 因此在yc++中,不必再包含yca.h中的头文件,也不需要再指定DLL库。

/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
运行该例需将YC++的下列几个文件拷入你的源程序所在目录:

   YC01/yxbapi.dll    C/C++编译器, 浏览器内核库
   YC01/yxbimg.dll    图象, 动画解码库
   YC01/yxbext.dll    浏览器内核交互代码库

   YC01/examples/y.mdb    数据库文件, 它是用MS Access创建的, 其中只有一个表: me

/*****************************************************************************************************************/
将下列代码存入名字任取的文件, 如: blog4a.cpp
在yc++中, 用<文件/打开或创建cpp源程序>调入blog4a.cpp, 再用 <工具/执行>运行blog4a.cpp
   或在dos中, 用 ycc blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe
在vc++中, 用 cl blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe

/*****************************************************************************************************************/

#ifndef YCC     //yc++的头文件ycansi.h中定义了YCC标识符, 而其它编译器没有定义它
#include       
#include       
#include       
//#include       
//#include       
//#include       

#pragma         comment(lib, "user32.lib")
#pragma         comment(lib, "odbc32.lib")
#endif

#define  MAX_DB_FILEDS   100       //最大字段数
#define  MAX_DB_STRLEN   1024      //字段的最大长度

struct  DBObject
{
 UDWORD       fieldlen[MAX_DB_FILEDS];
 SWORD        fSqlType[MAX_DB_FILEDS];
 SQLCHAR      FieldStr[MAX_DB_FILEDS][MAX_DB_STRLEN];
 SQLSMALLINT  fieldnum;
 SQLHENV      hEnv;
 SQLHDBC      hDBC;
 SQLHSTMT     hstmt;
 SQLCHAR      colName[MAX_DB_FILEDS][256];
};

void main()
{
    char mdb_name[] = "y.mdb";      //要被操作的数据库文件名
    char table_name[] = "me";       //要被操作的数据库表名字

    DBObject  rdb;
    if(SQLAllocEnv(&rdb.hEnv) != SQL_SUCCESS)    return;     //分配ODBC环境
    if(SQLAllocConnect(rdb.hEnv,&rdb.hDBC) != SQL_SUCCESS)   //分配连接用内存
      {
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    SQLCHAR  szConnStr[1024],constr[MAX_PATH+128];
    sprintf((char*)constr,"DBQ=%s;DRIVER={Microsoft Access Driver (*.mdb)}", mdb_name);

    //加载驱动程序,连接源
    if(SQLDriverConnect(rdb.hDBC,NULL,constr,strlen((char*)constr),szConnStr,sizeof(szConnStr),NULL,SQL_DRIVER_NOPROMPT) != SQL_SUCCESS)
      {
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    if(SQLAllocStmt(rdb.hDBC,&rdb.hstmt) != SQL_SUCCESS)  //为SQL语句分配内存
      {
 SQLDisconnect(rdb.hDBC);
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    //设置SQL语句
    SQLCHAR  szStmt[255];
    strcpy((char*)szStmt,"SELECT * FROM ");
    strcat((char*)szStmt, table_name);
    SQLExecDirect(rdb.hstmt, szStmt, SQL_NTS);  //执行ODBC语句

    SQLNumResultCols(rdb.hstmt,&rdb.fieldnum);
    rdb.fieldnum = min(rdb.fieldnum, MAX_DB_FILEDS);

    for(int ii=0; ii      {
 SQLDescribeCol(rdb.hstmt,ii+1, rdb.colName[ii], sizeof rdb.colName[ii], NULL, &rdb.fSqlType[ii], &rdb.fieldlen[ii], NULL, NULL);
 SQLBindCol(rdb.hstmt, ii+1, SQL_C_DEFAULT, rdb.FieldStr[ii], MAX_DB_STRLEN, NULL);
      }

    //print
    void print_db(DBObject *pRdb);
    print_db(&rdb);

    //exit
    SQLCloseCursor(rdb.hstmt);
    SQLFreeStmt(rdb.hstmt,SQL_CLOSE);
    SQLDisconnect(rdb.hDBC);
    SQLFreeConnect(rdb.hDBC);
    SQLFreeEnv(rdb.hEnv);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BinToChar(char *outstr, char *instr, SDWORD count)
{
    char *ostr=outstr;
    while(count--)
      {
 UCHAR uletter = (*instr & 0xF0) >> 4;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
 uletter = *instr++ & 0x0F;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
      }
    *ostr = '/0';
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void get_db_field_text(DBObject *pRdb,int Col,char *outbuff)
{
static char szdate[] = "%02u/%02u/%02u";
static char sztime[] = "%02u:%02u:%02u";
static char sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";

    char *inbuff = (char*)pRdb->FieldStr[Col];
    *outbuff = '/0';

    switch(pRdb->fSqlType[Col])
      {
 case SQL_CHAR:
 case SQL_VARCHAR:
 case SQL_LONGVARCHAR:
      strcpy(outbuff,inbuff);
      break;
 case SQL_BINARY:
 case SQL_VARBINARY:
 case SQL_LONGVARBINARY:
      strcpy(outbuff, "0x");
      BinToChar(outbuff+2, (char*)inbuff, pRdb->fieldlen[Col]);
      break;
 case SQL_TINYINT:
 case SQL_SMALLINT:
      SWORD   FAR *tmpsword;
      tmpsword = (SWORD FAR *)inbuff;
      wsprintf(outbuff, "%d", *tmpsword);
      break;
 case SQL_BIT:
      tmpsword = (SWORD FAR *)inbuff;
      strcpy(outbuff, (*tmpsword) ? "1" : "0");
      break;
 case SQL_INTEGER:
 case SQL_BIGINT:
      SDWORD  FAR *tmpsdword;
      tmpsdword = (SDWORD FAR *)inbuff;
      wsprintf(outbuff, "%ld", *tmpsdword);
      break;
 case SQL_FLOAT:
 case SQL_DOUBLE:
      SDOUBLE FAR *tmpsdouble;
      tmpsdouble = (SDOUBLE FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsdouble);
      break;
 case SQL_REAL:
      SFLOAT  FAR *tmpsfloat;
      tmpsfloat = (SFLOAT FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsfloat);
      break;
 case SQL_DECIMAL:
 case SQL_NUMERIC:
      strcpy(outbuff, inbuff);
      break;
 case SQL_DATE:
      DATE_STRUCT FAR *tmpdate;
      tmpdate = (DATE_STRUCT FAR *)inbuff;
      wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
      break;
 case SQL_TIME:
      TIME_STRUCT FAR *tmptime;
      tmptime= (TIME_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
      break;
 case SQL_TIMESTAMP:
      TIMESTAMP_STRUCT FAR *tmptimestmp;
      tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month, tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,tmptimestmp->second, tmptimestmp->fraction);
      break;
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void print_db(DBObject *pRdb)
{
    printf("/n");
    for(int col=0; colfieldnum; col++)
      {
 printf((char*)pRdb->colName[col]);
 printf("/t");
      }
    for(;;)
      {
 if(SQLFetch(pRdb->hstmt) != SQL_SUCCESS)  break;

 printf("/n");
 for(int col=0; colfieldnum; col++)
   {
     char des_buf[MAX_DB_STRLEN];
     get_db_field_text(pRdb,col,des_buf);
     printf(des_buf);
     printf("/t");
   }
      }
    printf("/n");




                                                            如何用YC++操作数据库

     在YC++中,可以用多种方式操作数据库。这里列举了一个采用ODBC规范进行数据库编程的例子。
     ODBC提供了很多API函数, 这些函数及其使用到的结构、宏等的声明都在头文件sqlucode.h中, 这些函数
的二进制代码则在odbc32.dll库中。
     在vc++中, 若要使用ODBC的API函数, 则需要包含sqlucode.h,并指定链接文件odbc32.lib。
     在yc++中, 编译器默认包含了头文件: YC01/include/yca.h, 查看后可发现yca.h又包头文件sqlucode.h,
由于YC++会自动链接yca.h中声明的所有库函数, 因此在yc++中,不必再包含yca.h中的头文件,也不需要再指定DLL库。

/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
运行该例需将YC++的下列几个文件拷入你的源程序所在目录:

   YC01/yxbapi.dll    C/C++编译器, 浏览器内核库
   YC01/yxbimg.dll    图象, 动画解码库
   YC01/yxbext.dll    浏览器内核交互代码库

   YC01/examples/y.mdb    数据库文件, 它是用MS Access创建的, 其中只有一个表: me

/*****************************************************************************************************************/
将下列代码存入名字任取的文件, 如: blog4a.cpp
在yc++中, 用<文件/打开或创建cpp源程序>调入blog4a.cpp, 再用 <工具/执行>运行blog4a.cpp
   或在dos中, 用 ycc blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe
在vc++中, 用 cl blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe

/*****************************************************************************************************************/

#ifndef YCC     //yc++的头文件ycansi.h中定义了YCC标识符, 而其它编译器没有定义它
#include       
#include       
#include       
//#include       
//#include       
//#include       

#pragma         comment(lib, "user32.lib")
#pragma         comment(lib, "odbc32.lib")
#endif

#define  MAX_DB_FILEDS   100       //最大字段数
#define  MAX_DB_STRLEN   1024      //字段的最大长度

struct  DBObject
{
 UDWORD       fieldlen[MAX_DB_FILEDS];
 SWORD        fSqlType[MAX_DB_FILEDS];
 SQLCHAR      FieldStr[MAX_DB_FILEDS][MAX_DB_STRLEN];
 SQLSMALLINT  fieldnum;
 SQLHENV      hEnv;
 SQLHDBC      hDBC;
 SQLHSTMT     hstmt;
 SQLCHAR      colName[MAX_DB_FILEDS][256];
};

void main()
{
    char mdb_name[] = "y.mdb";      //要被操作的数据库文件名
    char table_name[] = "me";       //要被操作的数据库表名字

    DBObject  rdb;
    if(SQLAllocEnv(&rdb.hEnv) != SQL_SUCCESS)    return;     //分配ODBC环境
    if(SQLAllocConnect(rdb.hEnv,&rdb.hDBC) != SQL_SUCCESS)   //分配连接用内存
      {
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    SQLCHAR  szConnStr[1024],constr[MAX_PATH+128];
    sprintf((char*)constr,"DBQ=%s;DRIVER={Microsoft Access Driver (*.mdb)}", mdb_name);

    //加载驱动程序,连接源
    if(SQLDriverConnect(rdb.hDBC,NULL,constr,strlen((char*)constr),szConnStr,sizeof(szConnStr),NULL,SQL_DRIVER_NOPROMPT) != SQL_SUCCESS)
      {
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    if(SQLAllocStmt(rdb.hDBC,&rdb.hstmt) != SQL_SUCCESS)  //为SQL语句分配内存
      {
 SQLDisconnect(rdb.hDBC);
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    //设置SQL语句
    SQLCHAR  szStmt[255];
    strcpy((char*)szStmt,"SELECT * FROM ");
    strcat((char*)szStmt, table_name);
    SQLExecDirect(rdb.hstmt, szStmt, SQL_NTS);  //执行ODBC语句

    SQLNumResultCols(rdb.hstmt,&rdb.fieldnum);
    rdb.fieldnum = min(rdb.fieldnum, MAX_DB_FILEDS);

    for(int ii=0; ii      {
 SQLDescribeCol(rdb.hstmt,ii+1, rdb.colName[ii], sizeof rdb.colName[ii], NULL, &rdb.fSqlType[ii], &rdb.fieldlen[ii], NULL, NULL);
 SQLBindCol(rdb.hstmt, ii+1, SQL_C_DEFAULT, rdb.FieldStr[ii], MAX_DB_STRLEN, NULL);
      }

    //print
    void print_db(DBObject *pRdb);
    print_db(&rdb);

    //exit
    SQLCloseCursor(rdb.hstmt);
    SQLFreeStmt(rdb.hstmt,SQL_CLOSE);
    SQLDisconnect(rdb.hDBC);
    SQLFreeConnect(rdb.hDBC);
    SQLFreeEnv(rdb.hEnv);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BinToChar(char *outstr, char *instr, SDWORD count)
{
    char *ostr=outstr;
    while(count--)
      {
 UCHAR uletter = (*instr & 0xF0) >> 4;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
 uletter = *instr++ & 0x0F;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
      }
    *ostr = '/0';
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void get_db_field_text(DBObject *pRdb,int Col,char *outbuff)
{
static char szdate[] = "%02u/%02u/%02u";
static char sztime[] = "%02u:%02u:%02u";
static char sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";

    char *inbuff = (char*)pRdb->FieldStr[Col];
    *outbuff = '/0';

    switch(pRdb->fSqlType[Col])
      {
 case SQL_CHAR:
 case SQL_VARCHAR:
 case SQL_LONGVARCHAR:
      strcpy(outbuff,inbuff);
      break;
 case SQL_BINARY:
 case SQL_VARBINARY:
 case SQL_LONGVARBINARY:
      strcpy(outbuff, "0x");
      BinToChar(outbuff+2, (char*)inbuff, pRdb->fieldlen[Col]);
      break;
 case SQL_TINYINT:
 case SQL_SMALLINT:
      SWORD   FAR *tmpsword;
      tmpsword = (SWORD FAR *)inbuff;
      wsprintf(outbuff, "%d", *tmpsword);
      break;
 case SQL_BIT:
      tmpsword = (SWORD FAR *)inbuff;
      strcpy(outbuff, (*tmpsword) ? "1" : "0");
      break;
 case SQL_INTEGER:
 case SQL_BIGINT:
      SDWORD  FAR *tmpsdword;
      tmpsdword = (SDWORD FAR *)inbuff;
      wsprintf(outbuff, "%ld", *tmpsdword);
      break;
 case SQL_FLOAT:
 case SQL_DOUBLE:
      SDOUBLE FAR *tmpsdouble;
      tmpsdouble = (SDOUBLE FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsdouble);
      break;
 case SQL_REAL:
      SFLOAT  FAR *tmpsfloat;
      tmpsfloat = (SFLOAT FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsfloat);
      break;
 case SQL_DECIMAL:
 case SQL_NUMERIC:
      strcpy(outbuff, inbuff);
      break;
 case SQL_DATE:
      DATE_STRUCT FAR *tmpdate;
      tmpdate = (DATE_STRUCT FAR *)inbuff;
      wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
      break;
 case SQL_TIME:
      TIME_STRUCT FAR *tmptime;
      tmptime= (TIME_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
      break;
 case SQL_TIMESTAMP:
      TIMESTAMP_STRUCT FAR *tmptimestmp;
      tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month, tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,tmptimestmp->second, tmptimestmp->fraction);
      break;
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void print_db(DBObject *pRdb)
{
    printf("/n");
    for(int col=0; colfieldnum; col++)
      {
 printf((char*)pRdb->colName[col]);
 printf("/t");
      }
    for(;;)
      {
 if(SQLFetch(pRdb->hstmt) != SQL_SUCCESS)  break;

 printf("/n");
 for(int col=0; colfieldnum; col++)
   {
     char des_buf[MAX_DB_STRLEN];
     get_db_field_text(pRdb,col,des_buf);
     printf(des_buf);
     printf("/t");
   }
      }
    printf("/n");




                                                            如何用YC++操作数据库

     在YC++中,可以用多种方式操作数据库。这里列举了一个采用ODBC规范进行数据库编程的例子。
     ODBC提供了很多API函数, 这些函数及其使用到的结构、宏等的声明都在头文件sqlucode.h中, 这些函数
的二进制代码则在odbc32.dll库中。
     在vc++中, 若要使用ODBC的API函数, 则需要包含sqlucode.h,并指定链接文件odbc32.lib。
     在yc++中, 编译器默认包含了头文件: YC01/include/yca.h, 查看后可发现yca.h又包头文件sqlucode.h,
由于YC++会自动链接yca.h中声明的所有库函数, 因此在yc++中,不必再包含yca.h中的头文件,也不需要再指定DLL库。

/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
运行该例需将YC++的下列几个文件拷入你的源程序所在目录:

   YC01/yxbapi.dll    C/C++编译器, 浏览器内核库
   YC01/yxbimg.dll    图象, 动画解码库
   YC01/yxbext.dll    浏览器内核交互代码库

   YC01/examples/y.mdb    数据库文件, 它是用MS Access创建的, 其中只有一个表: me

/*****************************************************************************************************************/
将下列代码存入名字任取的文件, 如: blog4a.cpp
在yc++中, 用<文件/打开或创建cpp源程序>调入blog4a.cpp, 再用 <工具/执行>运行blog4a.cpp
   或在dos中, 用 ycc blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe
在vc++中, 用 cl blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe

/*****************************************************************************************************************/

#ifndef YCC     //yc++的头文件ycansi.h中定义了YCC标识符, 而其它编译器没有定义它
#include       
#include       
#include       
//#include       
//#include       
//#include       

#pragma         comment(lib, "user32.lib")
#pragma         comment(lib, "odbc32.lib")
#endif

#define  MAX_DB_FILEDS   100       //最大字段数
#define  MAX_DB_STRLEN   1024      //字段的最大长度

struct  DBObject
{
 UDWORD       fieldlen[MAX_DB_FILEDS];
 SWORD        fSqlType[MAX_DB_FILEDS];
 SQLCHAR      FieldStr[MAX_DB_FILEDS][MAX_DB_STRLEN];
 SQLSMALLINT  fieldnum;
 SQLHENV      hEnv;
 SQLHDBC      hDBC;
 SQLHSTMT     hstmt;
 SQLCHAR      colName[MAX_DB_FILEDS][256];
};

void main()
{
    char mdb_name[] = "y.mdb";      //要被操作的数据库文件名
    char table_name[] = "me";       //要被操作的数据库表名字

    DBObject  rdb;
    if(SQLAllocEnv(&rdb.hEnv) != SQL_SUCCESS)    return;     //分配ODBC环境
    if(SQLAllocConnect(rdb.hEnv,&rdb.hDBC) != SQL_SUCCESS)   //分配连接用内存
      {
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    SQLCHAR  szConnStr[1024],constr[MAX_PATH+128];
    sprintf((char*)constr,"DBQ=%s;DRIVER={Microsoft Access Driver (*.mdb)}", mdb_name);

    //加载驱动程序,连接源
    if(SQLDriverConnect(rdb.hDBC,NULL,constr,strlen((char*)constr),szConnStr,sizeof(szConnStr),NULL,SQL_DRIVER_NOPROMPT) != SQL_SUCCESS)
      {
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    if(SQLAllocStmt(rdb.hDBC,&rdb.hstmt) != SQL_SUCCESS)  //为SQL语句分配内存
      {
 SQLDisconnect(rdb.hDBC);
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    //设置SQL语句
    SQLCHAR  szStmt[255];
    strcpy((char*)szStmt,"SELECT * FROM ");
    strcat((char*)szStmt, table_name);
    SQLExecDirect(rdb.hstmt, szStmt, SQL_NTS);  //执行ODBC语句

    SQLNumResultCols(rdb.hstmt,&rdb.fieldnum);
    rdb.fieldnum = min(rdb.fieldnum, MAX_DB_FILEDS);

    for(int ii=0; ii      {
 SQLDescribeCol(rdb.hstmt,ii+1, rdb.colName[ii], sizeof rdb.colName[ii], NULL, &rdb.fSqlType[ii], &rdb.fieldlen[ii], NULL, NULL);
 SQLBindCol(rdb.hstmt, ii+1, SQL_C_DEFAULT, rdb.FieldStr[ii], MAX_DB_STRLEN, NULL);
      }

    //print
    void print_db(DBObject *pRdb);
    print_db(&rdb);

    //exit
    SQLCloseCursor(rdb.hstmt);
    SQLFreeStmt(rdb.hstmt,SQL_CLOSE);
    SQLDisconnect(rdb.hDBC);
    SQLFreeConnect(rdb.hDBC);
    SQLFreeEnv(rdb.hEnv);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BinToChar(char *outstr, char *instr, SDWORD count)
{
    char *ostr=outstr;
    while(count--)
      {
 UCHAR uletter = (*instr & 0xF0) >> 4;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
 uletter = *instr++ & 0x0F;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
      }
    *ostr = '/0';
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void get_db_field_text(DBObject *pRdb,int Col,char *outbuff)
{
static char szdate[] = "%02u/%02u/%02u";
static char sztime[] = "%02u:%02u:%02u";
static char sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";

    char *inbuff = (char*)pRdb->FieldStr[Col];
    *outbuff = '/0';

    switch(pRdb->fSqlType[Col])
      {
 case SQL_CHAR:
 case SQL_VARCHAR:
 case SQL_LONGVARCHAR:
      strcpy(outbuff,inbuff);
      break;
 case SQL_BINARY:
 case SQL_VARBINARY:
 case SQL_LONGVARBINARY:
      strcpy(outbuff, "0x");
      BinToChar(outbuff+2, (char*)inbuff, pRdb->fieldlen[Col]);
      break;
 case SQL_TINYINT:
 case SQL_SMALLINT:
      SWORD   FAR *tmpsword;
      tmpsword = (SWORD FAR *)inbuff;
      wsprintf(outbuff, "%d", *tmpsword);
      break;
 case SQL_BIT:
      tmpsword = (SWORD FAR *)inbuff;
      strcpy(outbuff, (*tmpsword) ? "1" : "0");
      break;
 case SQL_INTEGER:
 case SQL_BIGINT:
      SDWORD  FAR *tmpsdword;
      tmpsdword = (SDWORD FAR *)inbuff;
      wsprintf(outbuff, "%ld", *tmpsdword);
      break;
 case SQL_FLOAT:
 case SQL_DOUBLE:
      SDOUBLE FAR *tmpsdouble;
      tmpsdouble = (SDOUBLE FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsdouble);
      break;
 case SQL_REAL:
      SFLOAT  FAR *tmpsfloat;
      tmpsfloat = (SFLOAT FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsfloat);
      break;
 case SQL_DECIMAL:
 case SQL_NUMERIC:
      strcpy(outbuff, inbuff);
      break;
 case SQL_DATE:
      DATE_STRUCT FAR *tmpdate;
      tmpdate = (DATE_STRUCT FAR *)inbuff;
      wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
      break;
 case SQL_TIME:
      TIME_STRUCT FAR *tmptime;
      tmptime= (TIME_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
      break;
 case SQL_TIMESTAMP:
      TIMESTAMP_STRUCT FAR *tmptimestmp;
      tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month, tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,tmptimestmp->second, tmptimestmp->fraction);
      break;
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void print_db(DBObject *pRdb)
{
    printf("/n");
    for(int col=0; colfieldnum; col++)
      {
 printf((char*)pRdb->colName[col]);
 printf("/t");
      }
    for(;;)
      {
 if(SQLFetch(pRdb->hstmt) != SQL_SUCCESS)  break;

 printf("/n");
 for(int col=0; colfieldnum; col++)
   {
     char des_buf[MAX_DB_STRLEN];
     get_db_field_text(pRdb,col,des_buf);
     printf(des_buf);
     printf("/t");
   }
      }
    printf("/n");




                                                            如何用YC++操作数据库

     在YC++中,可以用多种方式操作数据库。这里列举了一个采用ODBC规范进行数据库编程的例子。
     ODBC提供了很多API函数, 这些函数及其使用到的结构、宏等的声明都在头文件sqlucode.h中, 这些函数
的二进制代码则在odbc32.dll库中。
     在vc++中, 若要使用ODBC的API函数, 则需要包含sqlucode.h,并指定链接文件odbc32.lib。
     在yc++中, 编译器默认包含了头文件: YC01/include/yca.h, 查看后可发现yca.h又包头文件sqlucode.h,
由于YC++会自动链接yca.h中声明的所有库函数, 因此在yc++中,不必再包含yca.h中的头文件,也不需要再指定DLL库。

/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
运行该例需将YC++的下列几个文件拷入你的源程序所在目录:

   YC01/yxbapi.dll    C/C++编译器, 浏览器内核库
   YC01/yxbimg.dll    图象, 动画解码库
   YC01/yxbext.dll    浏览器内核交互代码库

   YC01/examples/y.mdb    数据库文件, 它是用MS Access创建的, 其中只有一个表: me

/*****************************************************************************************************************/
将下列代码存入名字任取的文件, 如: blog4a.cpp
在yc++中, 用<文件/打开或创建cpp源程序>调入blog4a.cpp, 再用 <工具/执行>运行blog4a.cpp
   或在dos中, 用 ycc blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe
在vc++中, 用 cl blog4a.cpp 生成 blog4a.exe, 再运行blog4a.exe

/*****************************************************************************************************************/

#ifndef YCC     //yc++的头文件ycansi.h中定义了YCC标识符, 而其它编译器没有定义它
#include       
#include       
#include       
//#include       
//#include       
//#include       

#pragma         comment(lib, "user32.lib")
#pragma         comment(lib, "odbc32.lib")
#endif

#define  MAX_DB_FILEDS   100       //最大字段数
#define  MAX_DB_STRLEN   1024      //字段的最大长度

struct  DBObject
{
 UDWORD       fieldlen[MAX_DB_FILEDS];
 SWORD        fSqlType[MAX_DB_FILEDS];
 SQLCHAR      FieldStr[MAX_DB_FILEDS][MAX_DB_STRLEN];
 SQLSMALLINT  fieldnum;
 SQLHENV      hEnv;
 SQLHDBC      hDBC;
 SQLHSTMT     hstmt;
 SQLCHAR      colName[MAX_DB_FILEDS][256];
};

void main()
{
    char mdb_name[] = "y.mdb";      //要被操作的数据库文件名
    char table_name[] = "me";       //要被操作的数据库表名字

    DBObject  rdb;
    if(SQLAllocEnv(&rdb.hEnv) != SQL_SUCCESS)    return;     //分配ODBC环境
    if(SQLAllocConnect(rdb.hEnv,&rdb.hDBC) != SQL_SUCCESS)   //分配连接用内存
      {
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    SQLCHAR  szConnStr[1024],constr[MAX_PATH+128];
    sprintf((char*)constr,"DBQ=%s;DRIVER={Microsoft Access Driver (*.mdb)}", mdb_name);

    //加载驱动程序,连接源
    if(SQLDriverConnect(rdb.hDBC,NULL,constr,strlen((char*)constr),szConnStr,sizeof(szConnStr),NULL,SQL_DRIVER_NOPROMPT) != SQL_SUCCESS)
      {
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    if(SQLAllocStmt(rdb.hDBC,&rdb.hstmt) != SQL_SUCCESS)  //为SQL语句分配内存
      {
 SQLDisconnect(rdb.hDBC);
 SQLFreeConnect(rdb.hDBC);
 SQLFreeEnv(rdb.hEnv);
 return;
      }

    //设置SQL语句
    SQLCHAR  szStmt[255];
    strcpy((char*)szStmt,"SELECT * FROM ");
    strcat((char*)szStmt, table_name);
    SQLExecDirect(rdb.hstmt, szStmt, SQL_NTS);  //执行ODBC语句

    SQLNumResultCols(rdb.hstmt,&rdb.fieldnum);
    rdb.fieldnum = min(rdb.fieldnum, MAX_DB_FILEDS);

    for(int ii=0; ii      {
 SQLDescribeCol(rdb.hstmt,ii+1, rdb.colName[ii], sizeof rdb.colName[ii], NULL, &rdb.fSqlType[ii], &rdb.fieldlen[ii], NULL, NULL);
 SQLBindCol(rdb.hstmt, ii+1, SQL_C_DEFAULT, rdb.FieldStr[ii], MAX_DB_STRLEN, NULL);
      }

    //print
    void print_db(DBObject *pRdb);
    print_db(&rdb);

    //exit
    SQLCloseCursor(rdb.hstmt);
    SQLFreeStmt(rdb.hstmt,SQL_CLOSE);
    SQLDisconnect(rdb.hDBC);
    SQLFreeConnect(rdb.hDBC);
    SQLFreeEnv(rdb.hEnv);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BinToChar(char *outstr, char *instr, SDWORD count)
{
    char *ostr=outstr;
    while(count--)
      {
 UCHAR uletter = (*instr & 0xF0) >> 4;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
 uletter = *instr++ & 0x0F;
 if(uletter <= 9)        *ostr++ = uletter + '0';
 else                    *ostr++ = 'A' + (uletter - 10);
      }
    *ostr = '/0';
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void get_db_field_text(DBObject *pRdb,int Col,char *outbuff)
{
static char szdate[] = "%02u/%02u/%02u";
static char sztime[] = "%02u:%02u:%02u";
static char sztimestmp[] = "%02u/%02u/%02u %02u:%02u:%02u.%lu";

    char *inbuff = (char*)pRdb->FieldStr[Col];
    *outbuff = '/0';

    switch(pRdb->fSqlType[Col])
      {
 case SQL_CHAR:
 case SQL_VARCHAR:
 case SQL_LONGVARCHAR:
      strcpy(outbuff,inbuff);
      break;
 case SQL_BINARY:
 case SQL_VARBINARY:
 case SQL_LONGVARBINARY:
      strcpy(outbuff, "0x");
      BinToChar(outbuff+2, (char*)inbuff, pRdb->fieldlen[Col]);
      break;
 case SQL_TINYINT:
 case SQL_SMALLINT:
      SWORD   FAR *tmpsword;
      tmpsword = (SWORD FAR *)inbuff;
      wsprintf(outbuff, "%d", *tmpsword);
      break;
 case SQL_BIT:
      tmpsword = (SWORD FAR *)inbuff;
      strcpy(outbuff, (*tmpsword) ? "1" : "0");
      break;
 case SQL_INTEGER:
 case SQL_BIGINT:
      SDWORD  FAR *tmpsdword;
      tmpsdword = (SDWORD FAR *)inbuff;
      wsprintf(outbuff, "%ld", *tmpsdword);
      break;
 case SQL_FLOAT:
 case SQL_DOUBLE:
      SDOUBLE FAR *tmpsdouble;
      tmpsdouble = (SDOUBLE FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsdouble);
      break;
 case SQL_REAL:
      SFLOAT  FAR *tmpsfloat;
      tmpsfloat = (SFLOAT FAR *)inbuff;
      sprintf(outbuff, "%Fg", *tmpsfloat);
      break;
 case SQL_DECIMAL:
 case SQL_NUMERIC:
      strcpy(outbuff, inbuff);
      break;
 case SQL_DATE:
      DATE_STRUCT FAR *tmpdate;
      tmpdate = (DATE_STRUCT FAR *)inbuff;
      wsprintf(outbuff, szdate, tmpdate->month, tmpdate->day, tmpdate->year);
      break;
 case SQL_TIME:
      TIME_STRUCT FAR *tmptime;
      tmptime= (TIME_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztime, tmptime->hour, tmptime->minute, tmptime->second);
      break;
 case SQL_TIMESTAMP:
      TIMESTAMP_STRUCT FAR *tmptimestmp;
      tmptimestmp = (TIMESTAMP_STRUCT FAR *)inbuff;
      wsprintf(outbuff, sztimestmp, tmptimestmp->year, tmptimestmp->month, tmptimestmp->day, tmptimestmp->hour, tmptimestmp->minute,tmptimestmp->second, tmptimestmp->fraction);
      break;
 }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void print_db(DBObject *pRdb)
{
    printf("/n");
    for(int col=0; colfieldnum; col++)
      {
 printf((char*)pRdb->colName[col]);
 printf("/t");
      }
    for(;;)
      {
 if(SQLFetch(pRdb->hstmt) != SQL_SUCCESS)  break;

 printf("/n");
 for(int col=0; colfieldnum; col++)
   {
     char des_buf[MAX_DB_STRLEN];
     get_db_field_text(pRdb,col,des_buf);
     printf(des_buf);
     printf("/t");
   }
      }
    printf("/n");