第一步:配置ODBC。

①、在控制面板找到ODBC,或者在控制面板上搜索ODBC。如图:

②、点击ODBC的添加按钮,选择SQL Server,这是会出现创建SQL Server的新数据源的对话框,我以phonesql为名建立名称,选择SQL登陆的服务器,再点击下一步,选择登陆方式:网络登陆、用户输入登陆,任选(我选择用户输入登陆,以:用户名sa  密码123456为例 )。

                      

③、选择数据库test(我在SQL里面建的test),然后一直点下一步。最后点测试数据源。最后显示测试成功。

             

这样ODBC就建立好了,接下来的工作就是连接数据库了。

第二步:建立数据库的表和添加数据。

    CREATE TABLE [dbo].[worker](
[num] [int] NOT NULL,
[name] [char](20) NOT NULL,
[sex] [char](10) NOT NULL,
[age] [int] NOT NULL,
[shenfennum] [char](20) NOT NULL,
[xueli] [char](10) NOT NULL,
[mianmao] [char](10) NOT NULL,
[mima] [char](20) NOT NULL,
[quanxian] [char](10) NOT NULL,
[born] [char](20) NOT NULL
) ON [PRIMARY]

第三步:使用VC++访问数据库。
①、引用头文件
#include<stdio.h>
#include<windows.h>
#include<sql.h>
#include<sqlext.h>
#include<sqltypes.h>

  解释:1.   SQLINTEGER   定义一个整型变量,相当于C语言中的int。

       2.  SQLCHAR      定义一个字符变量,相当于C语言中的char.
3. ret=SQLConnect(hdbc,(SQLCHAR*)"phonesql",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"",SQL_NTS);//连接数据库
                               phonesql是建立的odbc的数据源,sa是用户名,123456是密码
代码如下:
#include<stdio.h>
#include<windows.h>
#include<sql.h>
#include<sqlext.h>
#include<sqltypes.h>
#include<string.h>
SQLINTEGER num1,age1;
SQLCHAR name1[20],sex1[10],shenfennum1[20],xueli1[10],mianmao1[10],mima1[20],quanxian1[10],born1[20];
SQLINTEGER len_num1,len_name1,len_sex1,len_shenfennum1,len_xueli1,len_age1,len_mianmao1,len_born1,len_mima1,len_quanxian1;
void fuzhi()
{
SQLRETURN ret;
SQLHENV henv;//SQLHANDLE henv
SQLHDBC hdbc;//SQLHANDLE hdbc
SQLHSTMT hstmt;//SQLHANDLE hstmt
ret=SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);//申请环境句柄
ret=SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER);//设置环境属性
ret=SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);//申请数据库连接句柄
ret=SQLConnect(hdbc,(SQLCHAR*)"phonesql",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"123456",SQL_NTS);//连接数据库
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO){
ret=SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);//申请SQL语句句柄
SQLCHAR sql[]="SELECT *FROM worker";
ret=SQLExecDirect(hstmt,sql,SQL_NTS);//直接执行SQL语句
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO){
int i=0;
while(SQLFetch(hstmt)!=SQL_NO_DATA){//遍历结果集
/*****************************************数据库整型赋值*******************************/
SQLGetData(hstmt,1,SQL_C_ULONG,&num1,0,&len_num1);
/************************************************************************************/
SQLGetData(hstmt,2,SQL_C_CHAR,name1,20,&len_name1);
SQLGetData(hstmt,3,SQL_C_CHAR,sex1,10,&len_sex1);
SQLGetData(hstmt,4,SQL_C_ULONG,&age1,0,&len_age1);
SQLGetData(hstmt,5,SQL_C_CHAR,shenfennum1,20,&len_shenfennum1);
SQLGetData(hstmt,6,SQL_C_CHAR,xueli1,10,&len_xueli1);
SQLGetData(hstmt,7,SQL_C_CHAR,mianmao1,10,&len_mianmao1);
SQLGetData(hstmt,8,SQL_C_CHAR,mima1,20,&len_mima1);
SQLGetData(hstmt,9,SQL_C_CHAR,quanxian1,10,&len_quanxian1);
SQLGetData(hstmt,10,SQL_C_CHAR,born1,10,&len_born1);
printf("%d %s %s %d %s %s %s %s %s %s\n",num1,name1,sex1,age1,shenfennum1,xueli1,mianmao1,mima1,quanxian1,born1);
}
SQLSMALLINT number_column;
ret=SQLNumResultCols(hstmt,&number_column);//查询结果集列数
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO)
printf("结果集共有%d列\n",number_column);
else printf("查询结果集列数失败!\n");
SQLINTEGER number_row;
ret=SQLRowCount(hstmt,&number_row);//查询被影响的行数
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO)
printf("结果集共有%d个记录\n",number_row);
else printf("查询结果集记录个数失败!\n"); SQLFreeHandle(SQL_HANDLE_STMT,hstmt);//释放语句句柄
}else printf("查询数据库操作失败!\n"); SQLDisconnect(hdbc);//断开与数据库的连接
}
else printf("连接数据库失败!\n");
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);//释放连接句柄
SQLFreeHandle(SQL_HANDLE_ENV,henv);//释放环境句柄
} /********************************************************/
int main(){
fuzhi(); return 0;
}
第四步:把获取的数据赋值给C语言中结构体中,使操作数据更方便(也可以直接用通过ODBC更改数据,个人觉得麻烦)。
①、定义结构体。
struct worker
{
int num;//工号
char name[20];//姓名
char sex[10];//性别
int age;//年龄
char shenfennum[20];//身份证号码
char xueli[10];//学历
char mianmao[10];//政治面貌
char mima[20];//密码
char quanxian[10];//权限设置
char born[20];//出生年月日
}gong[1000];

  ②、赋值。

                gong[i].num=num1;
gong[i].age=age1;
strcpy((char *)gong[i].name,(char *)name1);
strcpy((char *)gong[i].sex,(char *)sex1);
strcpy((char *)gong[i].shenfennum,(char *)shenfennum1);
strcpy((char *)gong[i].xueli,(char *)xueli1);
strcpy((char *)gong[i].mianmao,(char *)mianmao1);
strcpy((char *)gong[i].mima,(char *)mima1);
strcpy((char *)gong[i].quanxian,(char *)quanxian1);
strcpy((char *)gong[i].born,(char *)born1);

  注意:SQL里面char数据类型是当填写内容不足自身长度时,后面补足相应的空格。所以赋值时,也会把空格符号赋值给变量里面,导致后期处理数据有误。在SQL建表时:将char类型修改为Varchar类型,也可以写一个函数来去除多余的空格符。代码如下:

void trim(char *str)
{
int i,j,k;
char tmpstr[MAXSTRSIZE]; //可以动态分配一下,这里用静态的一般情况可以满足
i=strlen(str);
for(k=j=0;j<i;j++)
{
if(str[j]!=' ')
{
tmpstr[k]=str[j];k++;}
}
tmpstr[k]='\0';
strcpy(str,tmpstr);
}

  整体代码如下:

#include<stdio.h>
#include<windows.h>
#include<sql.h>
#include<sqlext.h>
#include<sqltypes.h>
#include<string.h>
#define MAXSTRSIZE 1024
SQLINTEGER num1,age1;
SQLCHAR name1[20],sex1[10],shenfennum1[20],xueli1[10],mianmao1[10],mima1[20],quanxian1[10],born1[20];
SQLINTEGER len_num1,len_name1,len_sex1,len_shenfennum1,len_xueli1,len_age1,len_mianmao1,len_born1,len_mima1,len_quanxian1;
struct worker
{
int num;//工号
char name[20];//姓名
char sex[10];//性别
int age;//年龄
char shenfennum[20];//身份证号码
char xueli[10];//学历
char mianmao[10];//政治面貌
char mima[20];//密码
char quanxian[10];//权限设置
char born[20];//出生年月日
}gong[1000];
void trim(char *str);
void fuzhi()
{
SQLRETURN ret;
SQLHENV henv;//SQLHANDLE henv
SQLHDBC hdbc;//SQLHANDLE hdbc
SQLHSTMT hstmt;//SQLHANDLE hstmt
ret=SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);//申请环境句柄
ret=SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER);//设置环境属性
ret=SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);//申请数据库连接句柄
ret=SQLConnect(hdbc,(SQLCHAR*)"phonesql",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"123456",SQL_NTS);//连接数据库
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO){
ret=SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);//申请SQL语句句柄
SQLCHAR sql[]="SELECT *FROM worker";
ret=SQLExecDirect(hstmt,sql,SQL_NTS);//直接执行SQL语句
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO){
int i=0;
while(SQLFetch(hstmt)!=SQL_NO_DATA){//遍历结果集
/*****************************************数据库整型赋值*******************************/
SQLGetData(hstmt,1,SQL_C_ULONG,&num1,0,&len_num1);
/************************************************************************************/
SQLGetData(hstmt,2,SQL_C_CHAR,name1,20,&len_name1);
SQLGetData(hstmt,3,SQL_C_CHAR,sex1,10,&len_sex1);
SQLGetData(hstmt,4,SQL_C_ULONG,&age1,0,&len_age1);
SQLGetData(hstmt,5,SQL_C_CHAR,shenfennum1,20,&len_shenfennum1);
SQLGetData(hstmt,6,SQL_C_CHAR,xueli1,10,&len_xueli1);
SQLGetData(hstmt,7,SQL_C_CHAR,mianmao1,10,&len_mianmao1);
SQLGetData(hstmt,8,SQL_C_CHAR,mima1,20,&len_mima1);
SQLGetData(hstmt,9,SQL_C_CHAR,quanxian1,10,&len_quanxian1);
SQLGetData(hstmt,10,SQL_C_CHAR,born1,10,&len_born1); gong[i].num=num1;
gong[i].age=age1;
strcpy((char *)gong[i].name,(char *)name1);
strcpy((char *)gong[i].sex,(char *)sex1);
strcpy((char *)gong[i].shenfennum,(char *)shenfennum1);
strcpy((char *)gong[i].xueli,(char *)xueli1);
strcpy((char *)gong[i].mianmao,(char *)mianmao1);
strcpy((char *)gong[i].mima,(char *)mima1);
strcpy((char *)gong[i].quanxian,(char *)quanxian1);
strcpy((char *)gong[i].born,(char *)born1);
trim(gong[i].name);//删除数据库赋值给字符串中的空格字符
trim(gong[i].sex);
trim(gong[i].shenfennum);
trim(gong[i].xueli);
trim(gong[i].mianmao);
trim(gong[i].mima);
trim(gong[i].quanxian);
trim(gong[i].born);
printf("\n***********************结构体数据测试第%d个数据*****************************\n",i+1);
printf("\n\n**************************************************************************\n");
printf(" 工号: %d 姓名: %s 性别: %s 身份证号码: %s \n 学历: %s",gong[i].num,gong[i].name,gong[i].sex,gong[i].shenfennum,gong[i].xueli);
printf("政治面貌: %s 密码%s , 权限:%s 出生年月%s",gong[i].mianmao,gong[i].mima,gong[i].quanxian,gong[i].born);
printf("年纪:%d岁 \n\n",gong[i].age);
printf("**************************************************************************\n");
i++;
}
SQLSMALLINT number_column;
ret=SQLNumResultCols(hstmt,&number_column);//查询结果集列数
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO)
printf("结果集共有%d列\n",number_column);
else printf("查询结果集列数失败!\n"); SQLINTEGER number_row;
ret=SQLRowCount(hstmt,&number_row);//查询被影响的行数
if(ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO)
printf("结果集共有%d个记录\n",number_row);
else printf("查询结果集记录个数失败!\n"); SQLFreeHandle(SQL_HANDLE_STMT,hstmt);//释放语句句柄
}else printf("查询数据库操作失败!\n"); SQLDisconnect(hdbc);//断开与数据库的连接
}
else printf("连接数据库失败!\n");
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);//释放连接句柄
SQLFreeHandle(SQL_HANDLE_ENV,henv);//释放环境句柄
}
void trim(char *str)
{
int i,j,k;
char tmpstr[MAXSTRSIZE]; //可以动态分配一下,这里用静态的一般情况可以满足
i=strlen(str);
for(k=j=0;j<i;j++)
{
if(str[j]!=' ')
{
tmpstr[k]=str[j];k++;}
}
tmpstr[k]='\0';
strcpy(str,tmpstr);
}
/********************************************************/
int main(){
fuzhi(); return 0;
}

  

  显示结果如下:

C语言+ODBC+SQL 连接的更多相关文章

  1. C语言+ODBC+SQL 操作(向SQL里面添加数据)

    为了节省时间,我就引用上一节的数据库的表和C语言的结构体数组,在结构体数组中添加数据,清空数据库数据. 第一步查询:SQLBindParameter函数的用法. SQLRETURN SQLBindPa ...

  2. 连接SQLServer2005失败--[Microsoft][ODBC SQL Server Driver][DBNETLIB]一般性网络错误。请检查网络文档

    连接SQLServer2005失败,错误信息: 错误类型:Microsoft OLE DB Provider for ODBC Drivers (0x80004005)[Microsoft][ODBC ...

  3. firedac odbc sql server driver连接占线导致另一个hstmt

    firedac odbc sql server driver连接占线导致另一个hstmt 原因:FDQuery.FetchOptions.Mode=fmOnDemand.好像是为了性能问题,不设置则默 ...

  4. 细聊Oracle通过ODBC数据源连接SQL Server数据库

    类似文章搜索引擎上有很多,内容大致相同,今天所谓细聊是因为我在借鉴这些文章时候走了些弯路,所以写此文,为自己备忘,同时如果能为初涉此处知识点的小伙伴提供些帮助就更好了,文章结尾处的一些扩展有一定实战意 ...

  5. MSSQL Server数据库的四种连接方法和sql连接字符串

    MSSQL Server数据库的四种连接方法和sql连接字符串 分类: [ 03 ] C#(131) [ 07 ] SQL Server(68) [ 01 ] .NET(189) 今天用SQL Ser ...

  6. PowerDesigner反向数据库时遇到[Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句。SQLSTATE = 37错误解决方法

    逆向工程中,有时会出现如下错误 ... [Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句 SQLSTATE = 37000 解决方案: 1. ...

  7. [Oracle][ODBC SQL Server Driver][SQL Server]对象名 'RECOVER.HS_TRANSACTION_LOG' 无效(转)

    原帖由 qingyun 于 2010-6-21 15:44 发表 在写pl/sql的时候,有个很重要的注意点:比如:begin  update  某个sqlserver的表@dblink名字 .... ...

  8. 不安装Oracle客户端使用PL/SQL连接服务器端Oracle

    从10G开始,Oracle 提供了一个较为轻量级的客户包,叫做Instant Client Package. 将它安装好后,就不用再安装庞大的Oracle客户端,可以直接通过使用PL/SQL连接服务器 ...

  9. [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server 不存在或访问被拒绝

    一般连接sql数据库,IP_connstr="driver={SQL Server}; server=127.0.0.1;database=数据库名字;uid=sa;pwd=密码" ...

随机推荐

  1. vijosP1499炸毁燃料库

    背景 某天,外星人展开了对地球的侵略,OIer们开始与之周旋... 描述 外星人派出了172849个外星人乘着UFO来到地球,curimit神new带领着OIer们奋力抵抗.curimit神new觉得 ...

  2. Tomcat内存溢出详解【转载】

    本文转载自 http://elf8848.iteye.com/blog/378805 Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryEr ...

  3. E - QS Network - zoj 1586(简单)

    题意:在一个叫做QS的星系,他们使用一些特殊的通讯方式,两个人之间通讯需要使用一个网络适配器,但是一个网络适配器只能跟一个人联系,所有它连接几个人就需要及格适配器,而且每个人都有一些不同的偏好,喜欢的 ...

  4. 【Python排序搜索基本算法】之Prim算法

    Prim算法是实现最简单的最小生成树(MST)算法,适合于稠密图.要实现Prim算法,我们主要关注的是增量的变化,也就是从每个非树顶点到树顶点的最短距离,使得最后生成一棵包括所有顶点的树,并且这棵树的 ...

  5. MySQL慢查询(二) - pt-query-digest详解慢查询日志

    一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdu ...

  6. [LeetCode]Container With Most Water, 解题报告

    前言 难怪LeetCode OJ在找工作时被很多人推荐,发现了这道最大蓄水题目就是美团的笔试最后一道题,当时我霸笔只有着一道题目没有答出来,因此也就没有获得面试机会,可惜了 题目 Given n no ...

  7. jQuery UI Widget(1.8.1)工作原理--转载

    先看下代码的相关注释: /*! * jQuery UI Widget 1.8.1 * * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/abo ...

  8. angular指令浅谈

    今天在闲暇时间再次对angularjs的指令进行了初探,不探不知道一探吓一跳啊, 就一个简单的指令整整难住我了两个小时,先不说代码的逻辑是否复杂,就一些内部的一些实现让我看起来都是头疼的不行啊,不过最 ...

  9. Socket服务端口长连接最多能支持多少?

    答案是无限的.视服务端的资源而不同. 以前一直认为服务端在Accept客户端连接后,会开启一个新的端口与客户端建立链路,但这是错误的.事实上,一个连路是由Server IP+server Port + ...

  10. JAVA通过url获取页面内容

    String address = "http://sports.sina.com.cn/nba/live.html?id=2015050405"; URL url = new UR ...