《数据库系统概论》实验7报告

《数据库系统概论》实验报告

实验题目:通过ODBC方式访问数据库

实验环境:Windows 10、MySQL、SQL Server

实验步骤

一、MySQL数据源配置

1、安装MySQL的ODBC驱动安装包

https://dev.mysql.com/downloads/connector/odbc/,选择32位的8.0.21的msi版本,进行安装

2、添加驱动程序

打开控制面板——系统和安全——管理工具——ODBC数据源(32位),在用户DSN中添加MySQL ODBC 8.0 ANSI Driver

在这里插入图片描述

3、配置数据源

分别配置数据源名字、数据源描述(这个随意)、TCP/IP Server(设为本机)、端口、用户名、密码和数据库名,点击Test,如果成功则点击OK

在这里插入图片描述

4、注

如果出现了下面的情况,则需要在管理员模式下的命令提示符中使用语句net start 数据库名将数据库启动

在这里插入图片描述

二、SQL Server数据源配置

1、下载并安装SQL Server

在官网下载SSMS-Setup-CHS.exeSQL2019-SSEI-Dev.exe根据网上教程进行各种配置

双击SQL2019-SSEI-Dev.exe并根据网上教程进行各种配置(jdk使用了原来的版本,图为IDEA的Project Structure中的设置)

在这里插入图片描述

使用管理员模式运行SSMS-Setup-CHS.exe,然后不断下一步,最后重启即可完成安装

2、设置账户sa

打开Microsoft SQL Server Management Studio,在左侧的安全性——登录名中找到账户sa

在这里插入图片描述

右键sa,进入属性,配置好密码,服务器角色勾选上sysadmin

在这里插入图片描述

在这里插入图片描述

3、配置服务器连接

如图所示,配置服务器连接(我一开始用的是Windows身份认证,遇到了各种连不上的问题)

在这里插入图片描述

4、新建查询

在db_lab7_server数据库下创建一个course表

在这里插入图片描述

5、添加驱动程序并配置数据源

像MySQL部分一样,打开 ODBC数据源(32位),在用户DSN中添加ODBC Driver 17 for SQL Server并进行数据库相关信息的配置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三、代码部分

1、适用于MySQL的代码

#include <windows.h>
#include <iostream>
#include <assert.h>
#include <sql.h>
#include <sqlext.h>
using namespace std;
int main(){
    SQLHENV serverhenv;
    SQLHDBC serverhdbc;
    SQLHSTMT serverhstmt;
    SQLRETURN ret;
    SQLCHAR sno[20]={0},sex[20]={0},sname[20]={0},dept[20]={0},classno[20]={0},bdate[30]={0},cno[20]={0},cname[20]={0},semester[10]={10};
    SQLINTEGER grade=0,length;

    //分配环境句柄
    ret = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&serverhenv);

    //设置环境属性
    ret = SQLSetEnvAttr(serverhenv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
    if(!SQL_SUCCEEDED(ret))
    {
        cout<<"AllocEnvHandle error!"<<endl;
        system("pause");
    }

    //分配连接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC,serverhenv,&serverhdbc);
    if(!SQL_SUCCEEDED(ret))
    {
        cout<<"AllocDbcHandle error!"<<endl;
        system("pause");
    }

    //MySQL连接
    ret = SQLConnect(serverhdbc,(SQLCHAR*)"数据库名",SQL_NTS,(SQLCHAR*)"数据库用户名",SQL_NTS,(SQLCHAR*)"数据库密码",SQL_NTS);
    if(!SQL_SUCCEEDED(ret))
    //if(!(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO))
    {
        cout<<"SQL_Connect error!"<<endl;
        system("pause");
    }

    //分配执行语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT,serverhdbc,&serverhstmt);

    //执行SQL语句
    ret=SQLExecDirect(serverhstmt,(SQLCHAR*)"insert into course values('C01','数据库概论',01,6,'秋');",SQL_NTS);
    ret=SQLExecDirect(serverhstmt,(SQLCHAR*)"select cno,cname,semester from course",SQL_NTS);
    if(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO){
        //绑定数据
        SQLBindCol(serverhstmt,1, SQL_C_CHAR, (void*)cno,sizeof(cno), &length);
        SQLBindCol(serverhstmt,2, SQL_C_CHAR, (void*)cname,sizeof(cname), &length);
        SQLBindCol(serverhstmt,3, SQL_C_CHAR, (void*)semester,sizeof(semester), &length);
        //将光标移动到下行,即获得下行数据
        while(SQL_NO_DATA != SQLFetch(serverhstmt))
        {
            cout<<"cno:"<<cno<<" cname:"<<cname<<" semester:"<<semester;
            cout<<endl;
        }
    }

    //释放语句句柄
    ret=SQLFreeHandle(SQL_HANDLE_STMT,serverhstmt);
    if(SQL_SUCCESS!=ret && SQL_SUCCESS_WITH_INFO != ret)
        cout<<"free hstmt error!"<<endl;

    //断开数据库连接
    ret=SQLDisconnect(serverhdbc);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"disconnected error!"<<endl;

    //释放连接句柄
    ret=SQLFreeHandle(SQL_HANDLE_DBC,serverhdbc);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"free hdbc error!"<<endl;

    //释放环境句柄句柄
    ret=SQLFreeHandle(SQL_HANDLE_ENV,serverhenv);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"free henv error!"<<endl;
    system("pause");
}

2、适用于SQL Server的代码

#include <windows.h>
#include <iostream>
#include <assert.h>
#include <sql.h>
#include <sqlext.h>
using namespace std;
int main(){
    SQLHENV serverhenv;
    SQLHDBC serverhdbc;
    SQLHSTMT serverhstmt;
    SQLRETURN ret;
    SQLCHAR sno[20]={0},sex[20]={0},sname[20]={0},dept[20]={0},classno[20]={0},bdate[30]={0},cno[20]={0},cname[20]={0},semester[10]={10};
    SQLINTEGER grade=0,length;

    //分配环境句柄
    ret = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&serverhenv);

    //设置环境属性
    ret = SQLSetEnvAttr(serverhenv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
    if(!SQL_SUCCEEDED(ret))
    {
        cout<<"AllocEnvHandle error!"<<endl;
        system("pause");
    }

    //分配连接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC,serverhenv,&serverhdbc);
    if(!SQL_SUCCEEDED(ret))
    {
        cout<<"AllocDbcHandle error!"<<endl;
        system("pause");
    }

    //SQL Server连接
    ret = SQLConnect(serverhdbc,(SQLCHAR*)"数据库名",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"数据库密码",SQL_NTS);
    if(!SQL_SUCCEEDED(ret))
    //if(!(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO))
    {
        cout<<"SQL_Connect error!"<<endl;
        system("pause");
    }

    //分配执行语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT,serverhdbc,&serverhstmt);

    //执行SQL语句
    ret=SQLExecDirect(serverhstmt,(SQLCHAR*)"use db_lab7_server;",SQL_NTS);
    ret=SQLExecDirect(serverhstmt,(SQLCHAR*)"insert into course values('C01','数据库概论',01,6,'秋');",SQL_NTS);
    ret=SQLExecDirect(serverhstmt,(SQLCHAR*)"select cno,cname,semester from course",SQL_NTS);
    if(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO){
        //绑定数据
        SQLBindCol(serverhstmt,1, SQL_C_CHAR, (void*)cno,sizeof(cno), &length);
        SQLBindCol(serverhstmt,2, SQL_C_CHAR, (void*)cname,sizeof(cname), &length);
        SQLBindCol(serverhstmt,3, SQL_C_CHAR, (void*)semester,sizeof(semester), &length);
        //将光标移动到下行,即获得下行数据
        while(SQL_NO_DATA != SQLFetch(serverhstmt))
        {
            cout<<"cno:"<<cno<<" cname:"<<cname<<" semester:"<<semester;
            cout<<endl;
        }
    }

    //释放语句句柄
    ret=SQLFreeHandle(SQL_HANDLE_STMT,serverhstmt);
    if(SQL_SUCCESS!=ret && SQL_SUCCESS_WITH_INFO != ret)
        cout<<"free hstmt error!"<<endl;

    //断开数据库连接
    ret=SQLDisconnect(serverhdbc);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"disconnected error!"<<endl;

    //释放连接句柄
    ret=SQLFreeHandle(SQL_HANDLE_DBC,serverhdbc);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"free hdbc error!"<<endl;

    //释放环境句柄句柄
    ret=SQLFreeHandle(SQL_HANDLE_ENV,serverhenv);
    if(SQL_SUCCESS!=ret&&SQL_SUCCESS_WITH_INFO!=ret)
        cout<<"free henv error!"<<endl;
    system("pause");
}

四、运行结果

​ 代码其实就是执行如下指令

insert into course values('C01','数据库概论',01,6,'秋');
1、mysql部分
1)Codeblocks运行结果

在这里插入图片描述

2)数据库结果

在这里插入图片描述

2、SQL Server部分
1)Codeblocks运行结果

在这里插入图片描述

2)数据库结果

在这里插入图片描述

在这里插入图片描述

五、遇到的问题

一)32位而非64位

​问题:下载了MySQL的64位的8.0.29版本的驱动程序,配置完成后却连接不到数据源

​解决:查询网上资料,发现Codeblocks是32位的,需要对应的32位程序才能正常运行,所以下载MySQL的32位的8.0.29版本的驱动程序

二)8.0.21而非8.0.29

​问题:安装了MySQL的32位的8.0.29版本的驱动程序,创建新数据源里却看不到相关的选项

​解决:由于中途曾经配过Ubuntu中的数据源,发现8.0.29版本的驱动程序经常出问题,所以改成8.0.21版本的驱动程序

三)无法连接数据源

​问题:按照教程配置好数据源,代码却显示连接不到数据源

​解决:在同学的帮助下,发现代码的蓝框部分应当填写数据源的名称(原先填的是数据库名称)

在这里插入图片描述

四)添加use语句

​问题:对于SQL Server,发现始终无法进入这个if语句之中

在这里插入图片描述

​解决:回看MySQL的配置步骤,发现数据源中已经写好了连接的数据库名称,但是SQL Server并没有写明,这就导致了insert语句和select语句执行时并没有进入对应数据库,因此需要加入一条use语句进入数据库(即图中注释部分)

五)Ubuntu下安装部分

​ Ubuntu下的安装,起始于Windows下安装失败,决定转战Ubuntu,使用Postgresql和MySQL完成实验,但在配完了MySQL的数据源后,发现代码部分基本都有include <windows.h>,寻找良久,没有好的解决方案,于是重回Windows,下面是Ubuntu下的安装过程记录:

1、使用下面语句下载unixodbc及相关软件包
sudo apt-get install unixodbc
sudo apt-get install unixodbc unixodbc-dev
2、手动下载unixODBC

在这里插入图片描述

1)解压缩

tar xvf unixODBC-2.3.9.tar.gz

2)进入文件夹

cd unixODBC-2.3.9

3)编译

./configure
make
make install

4)测试安装结果(安装成功则显示版本号和驱动地址)

odbcinst -j

在这里插入图片描述

3、使用下面语句安装数据库
sudo apt-get install mysql-server mysql-client
4、手动安装驱动程序mysql_odbc_connector

1)刚开始下载最新版的8.0.29

在这里插入图片描述

2)不知道啥原因,我用8.0.29会报错

在这里插入图片描述

3)点击上图中的Archives,将驱动程序的版本换成8.0.21

在这里插入图片描述

在这里插入图片描述

5、配置驱动程序

1)使用下面语句打开相关文件(即测试安装结果中的DRIVERS)

sudo gedit /etc/odbcinst.ini

2)内容如下(我这里自动配好的)

[MySQL ODBC 8.0 Unicode Driver]
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so
UsageCount=1

[MySQL ODBC 8.0 ANSI Driver]
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8a.so
UsageCount=1
6、配置数据源

1)使用下面语句打开相关文件(即测试安装结果中的SYSTEM DATA SOURCES)

sudo gedit /etc/odbc.ini

2)内容如下

[MYSQL]
Driver = MySQL ODBC 8.0 ANSI Driver
Description = connection to MYSQL
Server = 127.0.0.1
Host = 127.0.0.1
Port = 3306
Database = mysql
CHARSET = UTF8
User = root
Password = 123456
SSLMODE = DISABLED
7、尝试连接数据库

发现无法连接,错误如下:

在这里插入图片描述

尝试使用mysql -u root -p进行连接,发现也无法连接,想起数据库刚安装,没有设置root用户的密码

8、设置MySQL的root用户的密码

1)使用下面指令查找数据库设置的随机账户和密码

sudo gedit /etc/mysql/debian.cnf

2)使用随机账户debian-sys-maint登录MySQL(密码随机生成,不要修改)

mysql -u debian-sys-maint -p

3)使用下面的SQL语句修改root用户的密码

use mysql;
update user set authentication_string='' where user='root';
alter user 'root'@'localhost' identified with mysql_native_password by '123456';
9、再次尝试连接

​ 成功!

在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值