如果你问为什么要用SQL Server,答:课程要求。
网上都是mysql的资料,SQL Server方面的资料需要在stackoverflow里找才有。
前置条件
- IDE: Codeblocks 或者 VS Or VC
- SQL Server已配置好,能用非windows方式登陆,推荐sa登陆,不能sa登陆的参考别人的博客
- 已配置了ODBC数据源
连接测试
Codeblocks版教程
- 官网下载安装odbc驱动,嫌访问速度慢的也可以在这里下载。下完安装,这个不用说了,一路next下去。
- Codeblocks菜单栏,Settings->Compiler settings->Linker settings添加CodeBlocks\MinGW\lib\libodbc32.a的绝对路径,参考下图。
- 新建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/(就是因为网上复制粘贴太多,资料才不好找)