返回列表 发帖

【教学视频】《C语言也能干大事》第十七节:数据库开发4

【秘籍:免费获得大量鹏币】|【立即购买鹏币(仅需5 元)】
帖子只需购买一次即可以永久使用,不需要每次访问的时候都购买。购买后将会看到如下的视频、资料等下载地址
本主题需向作者支付 50 鹏币 才能浏览 购买主题 已购买人数:541  记录
未购买此贴可以在线观看在线FLV格式的视频:
http://player.youku.com/player.php/sid/XODI3NDk5MzI=/v.swf
购买此贴后可以得到清晰版的下载地址。


购买此贴后可以得到全部源代码的下载
板书:

1、处理数据库查询


序号从1开始,不是0




  1. SQLINTEGER cbsatid=SQL_NTS;
  2.     while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
  3.     {
  4.                    SQLCHAR name[20];
  5.         SQLGetData(hstmt,1,SQL_C_CHAR,name,20,&cbsatid);
  6.     }
复制代码

  1. SQLINTEGER cbsatid=SQL_NTS;
  2. while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
  3. {
  4. SQLINTEGER i;
  5. SQLGetData(hstmt,2,SQL_C_LONG,&i,sizeof(SQLINTEGER),&cbsatid);
  6. }
复制代码



乱码问题解决方式,连接字符串使用GBK,修改数据库默认编码为gbk


4、保存HDBC到全局变量中,长连接、短连接。比如JavaC#中访问数据库复杂多少。一通百通。


要掌握调试的技巧,分析问题可能出错的原因和出错的地方,然后调试分析。一定不能和书上不一致,就懵了


5、自己动手写用户管理系统:新增密码字段、新建用户,检验登录;


  1. SQLINTEGER cbsatid=SQL_NTS;
  2. //需要一行一行的读取,这种方式就叫做通过游标读取,无论是在JDBC、ADO/ADO.net。。。结果集
  3. //调用SQLFetch一次就向下读取一行,直到返回值为SQL_NO_DATA_FOUND的时候表示读到了最后
  4. //是不是和C语言文件访问中EOF有点像。
  5.     while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
  6.     {
  7.   TCHAR name[20]; //字符数组,SQLCHAR其实就是char的一个别名,所以和char name[20]一样。
  8.   //调用SQLGetData来取列(Column)的内容
  9.   //第一个参数就是代表SQL语句的hstmt、第二是要读取的列的序号(从1开始)
  10.   //第三个是列的类型(SQL_C_CHAR字符串,在SQLExt.h中所有以SQL_C_开头的都是可选值)
  11.   //第四个参数就是要接收的值的指针!!!
  12.   //第五个是指针指向的缓冲区的大小
  13.   //第六个不用管,那么调就行
  14.         SQLGetData(hstmt,1,SQL_C_CHAR,name,sizeof(name)/sizeof(SQLCHAR),&cbsatid);
  15.   MessageBox(hwnd,name,TEXT(""),MB_OK);
  16.     }

  17. while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
  18.     {
  19.   SQLINTEGER i; //字符数组,SQLCHAR其实就是char的一个别名,所以和char name[20]一样。
  20.   //调用SQLGetData来取列(Column)的内容
  21.   //第一个参数就是代表SQL语句的hstmt、第二是要读取的列的序号(从1开始)
  22.   //第三个是列的类型(SQL_C_CHAR字符串,在SQLExt.h中所有以SQL_C_开头的都是可选值)
  23.   //第四个参数就是要接收的值的指针!!!
  24.   //第五个是指针指向的缓冲区的大小
  25.   //第六个不用管,那么调就行
  26.         SQLGetData(hstmt,2,SQL_C_LONG,&i,sizeof(i),&cbsatid);
  27.   TCHAR name[20];
  28.   SQLGetData(hstmt,1,SQL_C_CHAR,name,sizeof(name)/sizeof(TCHAR),&cbsatid);
  29.   TCHAR s[20];
  30.   wsprintf(s,TEXT("%s年龄是:%d"),name,i);
  31.   
  32.   MessageBox(hwnd,s,TEXT(""),MB_OK);
  33.     }
  34. result = SQLPrepare(hstmt,(SQLCHAR*)"select FUserName,FPassword from T_User",SQL_NTS);
  35. CHECKDBSTMTERROR(hwnd,result,hstmt);
  36.     result =SQLExecute(hstmt);
  37.     CHECKDBSTMTERROR(hwnd,result,hstmt);
  38. SQLINTEGER cbsatid=SQL_NTS;
  39. TCHAR inputUserName[20];
  40. GetDlgItemText(hwnd,IDC_EDITUSERNAME,inputUserName,sizeof(inputUserName)/sizeof(TCHAR));
  41. TCHAR inputPassword[20];
  42. GetDlgItemText(hwnd,IDC_EDITPASSWORD,inputPassword,sizeof(inputPassword)/sizeof(TCHAR));

  43. BOOL found=FALSE;
  44. while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
  45.     {
  46.   TCHAR userName[20];
  47.   SQLGetData(hstmt,1,SQL_C_CHAR,userName,sizeof(userName)/sizeof(TCHAR),&cbsatid);
  48.   TCHAR password[20];
  49.   SQLGetData(hstmt,2,SQL_C_CHAR,password,sizeof(password)/sizeof(TCHAR),&cbsatid);
  50.   if(0==lstrcmp(inputUserName,userName))
  51.   {
  52.    if(0==lstrcmp(inputPassword,password))
  53.    {
  54.     MessageBox(hwnd,TEXT("输入正确,登陆成功!"),TEXT("提示"),MB_OK);
  55.     found = TRUE;
  56.     break;
  57.    }
  58.   }
  59.     }
  60. if(FALSE==found)
  61. {
  62.   MessageBox(hwnd,TEXT("输入错误"),TEXT("报错"),MB_OK|MB_ICONERROR);
  63. }
复制代码



缺点是???
数据量大了以后运行速度很慢。比如说咱们如鹏100万会员。



Wsprintf


课下作业:


(1)
细化报错信息:当用户名不存在的时候提示“用户名不存在”,当用户名存在而密码错误的时候报告“密码错误”。


(2)
保存用户的时候,如果用户已经存在则更新已有的用户信息;否则新增用户信息。


(3)删除指定用户名的用户;


(4)有能力的同学研究ListView控件的使用,列出当前数据库中的所有用户信息,选择某个用户可以删除、可以更新。



下节课内容:


作业点评:ListView控件的使用与用户管理系统。


SQL注入漏洞及参数化SQL




购买主题 已购买人数:541  记录

原帖由 syx278250658 于 2009-8-19 11:29 发表
老师 那个while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND){} 之后 怎么才能使 SQLFetch(hstmt) 重新指向 数据头 我的意思就像 文件操作 EOF之后 用rewind(fp);又使文件指针指向 文件的首地址了

我是重新初始化hstmt
  1. //初始化语句句柄
  2. result = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
复制代码


然后就可以重新写SQL语句,然后执行,每执行一条新的SQL之前都要初始化hstmt哦
1

评分人数

没有最好,只有更好

TOP

最近课程比较紧,今天终于有时间跟上老师的课程,花了一个晚上的时间完成了老师布置的作业.
用的是咋如鹏版的MYSQL,
如果用SQL SERVER 2000的话只需把下面这行代码
SQLCHAR ConnStrIn[MAXBUFLEN] = "DRIVER={MYSQL ODBC 5.1 DRIVER};SERVER=127.0.0.1;UID=root;PWD=root;DATABASE=function321;CharSet=gbk;";
改为
SQLCHAR ConnStrIn[MAXBUFLEN] = "DRIVER={SQL SERVER};SERVER=127.0.0.1;UID="";PWD="";DATABASE=function321;CharSet=gbk;";
以Windows身份登录SQL查询分析器就可以,因为SQL SERVER已经安装了ODBC驱动所以不用再单独安装。
学习了HackHou同学的代码给对话框添加了颜色,还有实现了之前老师布置的只允许运行一个实例的功能
不过最少化托盘功能还没有实现,就先交了~礼拜有时间再添加其他功能
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
1

评分人数

    • CALF: 感谢分享鹏币 + 2

TOP


用的DBMS是MSSQLServer
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
1

评分人数

TOP

支持老大,老大注意身体,辛苦了

TOP

老大辛苦了!
[fly]三维动画学习中……fly]
kider@rupeng.com

TOP

热泪盈眶啊,终于看到最喜欢的东西了

嵌入式数据库开发,这个以后要派上大用场啊

TOP

老师辛苦了!!!继续学习!
往日成空已了然,而今欣然迷茫,前事已成忧!晓知理,持之事,费之力,必成大器!

TOP

老哥,谢了,你太大公无私了,

你太大公无私了,,,,好伟大

TOP

钱要太多了,

我要发多少帖子啊,还是不要了

TOP

原帖由 zhaoqi870 于 2009-4-6 11:21 发表
我要发多少帖子啊,还是不要了

看别人是怎么获得几千鹏币的:
快速获得论坛积分的秘诀 http://www.rupeng.com/forum/thread-1040-1-2.html
如鹏币获得方法 http://www.rupeng.com/index.php/viewthread-1116

TOP

辛苦了,老大。
念念·相思·相念·相思

TOP

辛苦啦。。。。学习中

TOP

又出新课了,谢谢老师
提醒自己   08年6月30日开始自学C

TOP

这节课经典。。。。。。。

TOP

回帖赚取鹏币

TOP

恩啊,这么快又新课出来了啊???
未来的世界:方向比努力重要,能力比知识重要,健康比成绩重要,生活比文凭重要,情商比智商重要!

TOP

很好啊,不错不错

TOP

我发现这边年龄用char 也能读出来
while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND)
    {
  TCHAR name[20],name1[20],name2[20];
  SQLGetData(hstmt,1,SQL_C_CHAR,name,20,&cbsatid);
   SQLGetData(hstmt,2,SQL_C_CHAR,name1,20,&cbsatid);
  wsprintf(name2,TEXT("name:%s age:%s"),name,name1);
  MessageBox(hwnd,name2,TEXT(""),MB_OK);
    }

TOP

哈哈哈 不错哈的东东

TOP

辛苦了。。。我正在好好学习,从头开始。。。

TOP

额滴神啊,一个错误追踪了一个通宵,终于可以睡觉了。。。
不知道为什么老大这样能通过,我就死活通不过。。
最后那一小段。。
TCHAR Sql[100];
memset(Sql,'\0',sizeof(Sql));
wsprintf(Sql," Select FPassword from T_User where FUser='%s' ",inputUserName);
老大视频里说只要找FPassword就可以了的,后来在MySQL上写上面句sql语句才发现有错,改成" Select FUser,FPassword from T_User where FUser='%s' ",inputUserName);才OK了。。
在循环里面SQLGetData(hstmt,2,SQL_C_CHAR,password,_countof(password),&cbsatid);后面加个messagebox看了下,的确第二种方法一次循环就到了,第一种循环多太多了。
代码放在最后会出现内存不可读的错误,放在
SQLFreeStmt(hstmt,SQL_CLOSE);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
SQLFreeHandle(SQL_HANDLE_ENV,henv);
之前,也就是释放资源前OK,不行了,睡了。

TOP

原帖由 soullife 于 2009-7-11 06:17 发表
额滴神啊,一个错误追踪了一个通宵,终于可以睡觉了。。。
不知道为什么老大这样能通过,我就死活通不过。。
最后那一小段。。
TCHAR Sql[100];
memset(Sql,'\0',sizeof(Sql));
wsprintf(Sql," Select FPassw ...


SQLGetData(hstmt,2,SQL_C_CHAR,password,_countof(password),&cbsatid);
这句话的意思是取“第二列”的值,你写“Select FPassword from”根本不存在第二列,所以当然会出错了,明白了吗?

TOP

原帖由 杨中科 于 2009-7-11 10:24 发表


SQLGetData(hstmt,2,SQL_C_CHAR,password,_countof(password),&cbsatid);
这句话的意思是取“第二列”的值,你写“Select FPassword from”根本不存在第二列,所以当然会出错了,明白了吗?


哈哈,昨天泛糊涂了,睡了一觉才明白真正错在哪里,这么一个失误让我精进不少啊,杨老大真不是盖的,真学到了。。谢谢老师~~

TOP

和上面相邻的同学一样的问题

又学到了,我当时还以为杨老师打错了呢,后来仔细想想和老师讲的差不多,只是老师一语道破啊~

TOP

这个不错 逐步熟悉WINDOWS编程
谢谢了 可惜分不够买啊

TOP

原帖由 catface 于 2009-8-8 22:09 发表
这个不错 逐步熟悉WINDOWS编程
谢谢了 可惜分不够买啊

那就去宣传咱们的如鹏赚鹏币喽,我第一天赚了100多鹏币。

TOP

老师 那个while (SQLFetch(hstmt)!=SQL_NO_DATA_FOUND){} 之后 怎么才能使 SQLFetch(hstmt) 重新指向 数据头 我的意思就像 文件操作 EOF之后 用rewind(fp);又使文件指针指向 文件的首地址了
学习不是因为缺少时间而是缺少努力--MyBlog
  Studies this matter, lacks the time, but is lacks diligently.
                  ----xiao祥 加油 UP UP UP

TOP

支持楼主一下,楼主辛苦了!

TOP

终于出来了啊,辛苦了

TOP

返回列表