目录
一、实验目的:
练习Proc编程。
二、实验工具:
VMW虚拟机。
Oracle数据库。
gcc编译器。
注:因为本人物理机上缺乏相关插件,导致Oracle无法正常启动和使用,所以本次实验在虚拟机上完成。
三、准备工作:
1、在虚拟机上配置win10系统。
虚拟机安装包及windows系统镜像链接:
链接:https://pan.baidu.com/s/1uq0nAsLaQoSRedSqBnmckQ
提取码:gyet
安装虚拟机教程:
虚拟机不能连网?教你正确安装虚拟机_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1Ba4y1t7ic?spm_id_from=333.1007.top_right_bar_window_history.content.click[装机工具]VMware虚拟机安装及使用教程/解决Win10玩游戏卡顿、win7及win10激活工具..._哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1Cb41177pr?spm_id_from=333.1007.top_right_bar_window_history.content.click
2、Oracle11g:
链接:
链接:https://pan.baidu.com/s/1MGkqZK6ZmHxGACseJqX5RQ
提取码:q9h7
安装教程:
如果出现监听器错误,下面是解决办法:
安装好后设置环境变量(后面编译gcc代码要用到!!!)
3、安装和使用gcc:
(这步是跟大佬新学的,在此表示:非常感谢!)
四、开始实验
1、在Oracle数据库中建表并插入:
/**建立三张表,并插入数据 */
set feedback off;
show user;
drop table sc;
drop table s;
drop table c;
create table s(
sno char(4) not null primary key,
sname varchar2(10),
sex char(3),
dept varchar2(4),
age int
);
insert into s values('801','金贤重','男','CS',23);
insert into s values('802','李敏镐','男','MA',25);
insert into s values('803','那英','女','CS',41);
insert into s values('804','金秀贤','女','MA',24);
insert into s values('805','刘德华','男',null,52);
insert into s values('806','文章','男','CS',27);
insert into s values('807','刘欢','男','MA',51);
insert into s values('808','马伊琍','女','CS',36);
insert into s values('809','姚笛','女','MA',23);
insert into s values('810','周杰伦','男',null,39);
create table c(
cno char(3) primary key,
cname varchar2(20),
credit int
);
insert into c values('01','数据库概论',3);
insert into c values('02','OS',4);
insert into c values('03','OOP',2);
insert into c values('04','Java',3);
insert into c values('05','Python',3);
insert into c values('06','D语言讲座',2);
create table sc(
sno char(4),
cno char(3),
grade numeric(3),
constraint sc_pk primary key(sno,cno),
constraint sc_fk1 foreign key(sno) references s(sno),
constraint sc_fk2 foreign key(cno) references c(cno),
constraint sc_grade check (grade between 0 and 100 or grade is null)
);
insert into sc values('801','01',81);
insert into sc values('802','01',59);
insert into sc values('803','01',0);
insert into sc values('804','01',60);
insert into sc values('805','01',30);
insert into sc values('806','01',90);
insert into sc values('807','01',60);
insert into sc values('808','01',null);
insert into sc values('801','02',null);
insert into sc values('802','02',30);
insert into sc values('803','02',45);
insert into sc values('804','02',80);
insert into sc values('805','02',70);
insert into sc values('806','02',60);
insert into sc values('801','03',90);
insert into sc values('802','03',60);
insert into sc values('803','03',40);
insert into sc values('804','03',null);
insert into sc values('805','03',50);
insert into sc values('806','03',70);
insert into sc values('807','03',70);
insert into sc values('808','03',80);
insert into sc values('801','04',40);
insert into sc values('802','04',0);
insert into sc values('803','04',null);
insert into sc values('804','04',80);
insert into sc values('805','04',90);
insert into sc values('806','04',60);
insert into sc values('807','04',70);
insert into sc values('808','04',50);
insert into sc values('809','05',0);
commit;
select * from s;
select * from c;
select * from sc;
输出数据:
2、使用gcc进行proc编程
(3.3的步骤做好才能进行这步。)
(1)创建一个新的项目文件夹(可以是任意位置)
(2)将pc文件复制到此文件夹
(一开始只有这一个文件)
(3)编写Makefile文件
创建Makefile文件
在文件夹中新建一个文档,更改名字为Makefile,然后删去扩展名就可以了。
编写(也可创建完直接编写再删去扩展名):
#Project example_1
example: example.o
gcc -o example example.o $(ORACLE_HOME)\BIN\oci.dll
example.o: example.c
gcc -c example.c -I $(ORACLE_HOME)\precomp\public
example.c: example.pc
proc example.pc
.PHONY: clean
clean:
del example.o example.c example.exe
这里面的example是代码文件名可以按自己的文件名更改。
(4)DOS窗口执行指令进行编译
在该文件夹路径下输入cmd回车(下面的文件还没生成,图片中的其余是我之前做好的)
(5)在Dos窗口输入:
mingw32-make
(6)双击生成的exe文件就可以执行了
结果:
下面就可以做题了。
五、做题
第 1 题:
第 2 题:
原来的.pc文件代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
#include <sqlcpr.h>
void sql_error();//异常处理函数
int main()
{
exec sql include sqlca;
exec sql begin declare section;
char user_name[20];
char user_pwd[20];
char db_name[20];
char ip[20];
char port[20];
char url[100];
int i;
char s_no[6];
char s_name[10];
char s_sex[4];
int s_age;
int var_age;
exec sql end declare section;
/**输入登陆信息如下所示 */
exec sql whenever SQLERROR do sql_error(); //异常处理
printf("\n\n\b 欢迎登录学生年龄查询功能\n\n");
printf("\b\b IP地址:"); gets(ip);
printf("\b\b Port号:");gets(port);
printf("\b\b 数据库服务器名称:");gets(db_name);
printf("\b\b 用户名:"); gets(user_name);
printf("\b\b 密码:");gets(user_pwd);
strcpy(url,ip);
strcat(url,":");
strcat(url,port);
strcat(url,"/");
strcat(url,db_name);
exec sql connect :user_name
identified by :user_pwd using :url;
printf("\n\n 用户:%s 密码:%s,哈哈,登陆成功.\n",user_name,user_pwd);
system("pause");
while(1)
{
system("cls");
printf("\n温馨提示:键入9999退出系统");
printf("\n输入年龄: "); scanf("%d",&var_age);
if( var_age==9999) break;
exec sql declare sx cursor for
select sno,sname,sex,age from s where age<:var_age;
exec sql open sx;
i=0;
system("cls");
printf("\n\t\t学生(年龄 < %d)的基本信息表",var_age);
printf("\n\t---------------------------------------------");
printf("\n\t序号\t学号\t姓名\t\t性别\t年龄");
printf("\n\t---------------------------------------------");
while(1)
{
exec sql fetch sx into :s_no,:s_name,:s_sex, :s_age;
if(sqlca.sqlcode!=0) break;
i++;
printf("\n\t %d\t%s\t%s\t%s\t%d",i,s_no,s_name,s_sex,s_age);
}
printf("\n\t--------------------------------------------");
if(i!=0) printf("\n\t\t\t\t共%d人\n",i);
else printf("\n\t\t\t未找到年龄为%d学生!\n",var_age);
system("pause");
}
system("pause");
exec sql close sx;
exec sql commit release;
return 0;
}
void sql_error()
{
printf("SQL语句错误:错误代号:%d 错误描述:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
system("pause");
exit(0);
}
查询的是数据库表中的年龄小于x的学生的基本信息
代码1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
#include <sqlcpr.h>
void sql_error();//异常处理函数
int main()
{
exec sql include sqlca;
exec sql begin declare section;
char user_name[20];
char user_pwd[20];
char db_name[20];
char ip[20];
char port[20];
char url[100];
int i;
char s_no[6];
char s_name[10];
char s_sex[4];
char c_no[6];
char c_name[10];
char c_grade[4];
int s_age;
char var_dept[10];
exec sql end declare section;
/**输入登陆信息如下所示 */
exec sql whenever SQLERROR do sql_error(); //异常处理
printf("\n\n\b 欢迎登录各系学生信息查询功能\n\n");
printf("\b\b IP地址:"); gets(ip);
printf("\b\b Port号:");gets(port);
printf("\b\b 数据库服务器名称:");gets(db_name);
printf("\b\b 用户名:");gets(user_name);
printf("\b\b 密码:");gets(user_pwd);
strcpy(url,ip);
strcat(url,":");
strcat(url,port);
strcat(url,"/");
strcat(url,db_name);
exec sql connect :user_name
identified by :user_pwd using :url;
printf("\n\n 用户:%s 密码:%s,哈哈,登陆成功.\n",user_name,user_pwd);
system("pause");
while(1)
{
system("cls");
printf("\n温馨提示:键入eixt退出系统");
printf("\n输入系别: "); scanf("%s",&var_dept);
if( var_dept=="eixt") break;
exec sql declare sx cursor for
select sno,sname,sex,age from s where dept =: var_dept;
exec sql open sx;
i=0;
system("cls");
printf("\n\t\t%s学生信息表",var_dept);
printf("\n\t---------------------------------------------");
printf("\n\t序号\t学号\t姓名\t\t性别\t年龄");
printf("\n\t---------------------------------------------");
while(1)
{
exec sql fetch sx into :s_no,:s_name,:s_sex, :s_age;
if(sqlca.sqlcode!=0) break;
i++;
printf("\n\t %d\t%s\t%s\t%s\t%d",i,s_no,s_name,s_sex,s_age);
}
printf("\n\t--------------------------------------------");
system("pause");
}
system("pause");
exec sql close sx;
exec sql commit release;
return 0;
}
void sql_error()
{
printf("SQL语句错误:错误代号:%d 错误描述:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
system("pause");
exit(0);
}
输出结果:
代码2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
#include <sqlcpr.h>
void sql_error();//异常处理函数
int main()
{
exec sql include sqlca;
exec sql begin declare section;
char user_name[20];
char user_pwd[20];
char db_name[20];
char ip[20];
char port[20];
char url[100];
int i;
char s_no[6];
char s_name[10];
char s_sex[4];
char c_no[6];
char c_name[20];
float c_grade;
int s_age;
char var_no[10];
exec sql end declare section;
/**输入登陆信息如下所示 */
exec sql whenever SQLERROR do sql_error(); //异常处理
printf("\n\n\b 欢迎登录学生各科成绩查询系统\n\n");
printf("\b\b IP地址:"); gets(ip);
printf("\b\b Port号:");gets(port);
printf("\b\b 数据库服务器名称:");gets(db_name);
printf("\b\b 用户名:");gets(user_name);
printf("\b\b 密码:");gets(user_pwd);
strcpy(url,ip);
strcat(url,":");
strcat(url,port);
strcat(url,"/");
strcat(url,db_name);
exec sql connect :user_name
identified by :user_pwd using :url;
printf("\n\n 用户:%s 密码:%s,哈哈,登陆成功.\n",user_name,user_pwd);
system("pause");
while(1)
{
system("cls");
printf("\n温馨提示:键入eixt退出系统");
printf("\n输入学号: "); scanf("%s",&var_no);
if( var_no=="eixt") break;
exec sql declare sx cursor for
select cname,grade
from c,sc
where sc.cno = c.cno
and sc.sno=:var_no
and grade is not null;
exec sql open sx;
i=0;
float sum=0;
system("cls");
printf("\n\t\t%s学生信息表",var_no);
printf("\n\t---------------------------------------------");
printf("\n\t序号\t课程名\t成绩\t");
printf("\n\t---------------------------------------------");
while(1)
{
exec sql fetch sx into :c_name,:c_grade;
if(sqlca.sqlcode!=0) break;
i++; sum=sum+c_grade;
printf("\n\t %d\t%s\t%.2f\t",i,c_name,c_grade);
}
printf("\n\t--------------------------------------------");
printf("\n\t---------------平均分:%.2f--------------",sum/i);
system("pause");
}
system("pause");
exec sql close sx;
exec sql commit release;
return 0;
}
void sql_error()
{
printf("SQL语句错误:错误代号:%d 错误描述:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
system("pause");
//exit(0);
}
遇到的问题:
解决办法是:
在查询条件中加入这句代码,跳过成绩空值。
and grade is not null;
输出:
六、结语:
我喜欢MySQL。