C语言连接SQL Server 2008

 

如果你问为什么要用SQL Server,答:课程要求。  

 

网上都是mysql的资料,SQL Server方面的资料需要在stackoverflow里找才有。

 

前置条件

  • IDE: Codeblocks 或者 VS Or VC
  • SQL Server已配置好,能用非windows方式登陆,推荐sa登陆,不能sa登陆的参考别人的博客
  • 已配置了ODBC数据源

连接测试

Codeblocks版教程

  1. 官网下载安装odbc驱动,嫌访问速度慢的也可以在这里下载。下完安装,这个不用说了,一路next下去。
  2. Codeblocks菜单栏,Settings->Compiler settings->Linker settings添加CodeBlocks\MinGW\lib\libodbc32.a的绝对路径,参考下图。 
  3. 新建cpp文件,贴下面代码
#include <iostream>
#include <windows.h>
#include <sqlext.h>

int main() {

    SQLHENV env;        //environment handle
    SQLHDBC dbc;        //connection handle
    SQLHSTMT stmt;      //state handle
    SQLRETURN ret;      //result return

    /* Allocate an environment handle */
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
    /* We need ODBC 3 support */
    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
    /* Allocate a connection handle */
    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
    /* Connect to the odbc */
    SQLDriverConnectW(dbc, NULL, L"DRIVER={SQL Server};SERVER=(local);DATABASE=students;UID=sa;PWD=password;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    /* Check for success */
    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))
    {
        std::cout << "Failed to connect" << std::endl;
    }
    else
    {
        std::cout << "Succeed to connect" << std::endl;

        /*  close connection */
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        SQLDisconnect(dbc);
        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
        SQLFreeHandle(SQL_HANDLE_ENV, env);
    }

    std::cin.get();
    return 0;
}

UID=sa;PWD=password为你的数据库账户密码,运行。结果为Succeed to connect那就OK了。

Visual Studio、VC教程

这个简单了,贴代码,改账号密码直接跑就行了。谁让它是微软自家的。

 

代码样例

SELECT查询

例如:SC表里查询基础数据

#include <iostream>
#include <windows.h>
#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>
#define NAME_LEN 20
#define SNO_LEN 7
#define CNO_LEN 6

int main() {

    SQLHENV env;        
    SQLHDBC dbc;        
    SQLHSTMT stmt;      
    SQLRETURN ret;      

    //查询的结果返回到这些变量里
    SQLCHAR sno[SNO_LEN], cno[CNO_LEN];
    SQLINTEGER grade;

    SQLINTEGER cbSno = SQL_NTS, cbGrade = 0, cbCno = SQL_NTS;
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);

    SQLDriverConnectW(dbc, NULL, L"DRIVER={SQL Server};SERVER=(local);DATABASE=students;UID=sa;PWD=password;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))
    {
        std::cout << "Failed to connect" << std::endl;
    }
    else
    {
        std::cout << "Succeed to connect" << std::endl;

        /* 基本上每个SQLExecDirect()都要初始化句柄 */
        ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
        ret = SQLSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)SQL_BIND_BY_COLUMN, SQL_IS_INTEGER);

        //查询
        ret = SQLExecDirect(stmt, (SQLCHAR *)("SELECT * FROM SC"), SQL_NTS);
        if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
        {
            /*  句柄、列、变量类型、接收缓冲、缓冲长度、返回的长度   */
            ret = SQLBindCol(stmt, 1, SQL_C_CHAR, sno, SNO_LEN, &cbSno);
            ret = SQLBindCol(stmt, 2, SQL_C_CHAR, cno, CNO_LEN, &cbCno);
            ret = SQLBindCol(stmt, 3, SQL_C_LONG, &grade, 0, &cbGrade);
        }
        //遍历数据
        while ((ret = SQLFetch(stmt)) != SQL_NO_DATA_FOUND)
        {
            if (ret == SQL_ERROR)   printf("fetch error\n");
            else
            {
                printf("sno=%s cno=%s grade=%d\n", sno, cno, grade);
            }
        }

        /*  关闭连接 */
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        SQLDisconnect(dbc);
        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
        SQLFreeHandle(SQL_HANDLE_ENV, env);

    }

    std::cin.get();
    return 0;
}

每条操作都要返回给ret(SQLRETURN类型变量)。 
比较关键的是SQLBindCol(句柄, 列, 变量类型, 接收缓冲, 缓冲长度, 实际长度)函数,参数类型如上。

参数解释:

  • 变量类型:如名,但如果是Integer这种整数就用SQL_C_LONG,因为并没有SQL_C_Integer
  • 接收缓冲:如名,该参数是个地址,所以如果是整数类型需要加&
  • 缓冲长度:如名,是字符串就给最大长度,这个长度按照数据库中标的设计就行,不过存中文的话建议*2+2。如果是整数这种不确定长度的直接传0进去。
  • 实际长度:如名,是查询结果返回到的实际长度,也是传指针,又或者说引用。你也许会用到,也许用不到该变量。

查询结果:

查询结果返回到stmt(SQLHSTMT类型)中,通过SQLFetch返回结果集合,代码是个玩过数据库的都看得懂了。

  while ((ret = SQLFetch(stmt)) != SQL_NO_DATA_FOUND) {
            if (ret == SQL_ERROR)   printf("fetch error\n");
            else{
                printf("sno=%s cno=%s grade=%d\n", sno, cno, grade);
            }
        }

Insert等非查询性数据

//删除信息管理系考试成绩小于50分的学生的该门程序的修课记录。
ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
ret = SQLSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)SQL_BIND_BY_COLUMN, SQL_IS_INTEGER);
ret = SQLExecDirect(stmt, (SQLCHAR *)("DELETE FROM SC  FROM SC, Student WHERE sDept = '信息管理系' AND Grade < 50 AND Student.Sno = SC.Sno"), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
    printf("\t成功删除\n");
}
else {
    printf("\t删除失败,也许是已经删除了\n");
}

转载请注明出处http://blog.csdn.net/u012469987/(就是因为网上复制粘贴太多,资料才不好找)
 

 

 

 

  • 7
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值