C语言连接SQL Server 2008

来源:互联网 发布:c语言项目开发实战 编辑:程序博客网 时间:2024/05/09 11:18
如果你问为什么要用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 6int 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/(就是因为网上复制粘贴太多,资料才不好找)



0 0
原创粉丝点击