mysql5.0以后就支持存储过程了,目前mysql的6.0Alpha版也已经推出。6.0不仅支持大型数据库如oracle等的绝大部分功 能,如存储过程、视图、触发器、job等等,而且修正了这些功能所存在的bug,其中6.0.1还支持64位windows,以及表空间。
在c/c++中访问mysql,常见的只是一些简单的业务,使用c中嵌入简单的查询、 插入、更新等操作即可。随着业务的复杂化,完成一个业务功能需要非常多的sql操作环节,把这些语句都嵌入c代码中会导致c代码越来越繁琐、不清晰,这时 候,自然就想到了存储过程来封装所有的数据库逻辑,通过c简单调用mysql存储过程接口即可达到目的,极大地减轻了c程序员的工作量,也便于前端业务处 理逻辑与数据库处理逻辑的分离。下面就介绍c语言调用存储过程的简单的方法。
1、首先创建一张表
用于存放用户信息
Create table student(
id int auto_increment,
name varchar(20),
age tinyint,
remark varchar(50),
primary key(id)
);
2、插入几条信息
Insert into student values(1,"zhouys",90, "");
commit;
3、查看用户信息
mysql> select * from student;
+------+-----------+------+----------+
| id | name | age | remark |
+------+-----------+------+----------+
| 1 | zhouys | 90 | |
+------+-----------+------+-----------+
1 row in set (0.00 sec)
mysql>
4、创建存储过程
如下:
delimiter //
create procedure querystudent(
in in_id int , #0- 字符id 1-数字id
#
out out_ret int, # 返回结果
out out_name varchar(20), # 名字
out out_age int # 年龄
)
label_a:begin
declare v_name varchar(20) ;
declare v_age tinyint ;
# 参数判断
if (in_id<=0) then
set out_ret=-1; #id error
leave label_a;
end if;
SELECT name,age into v_name,v_age from student where id=in_id limit 1;
if v_age is NULL then
set out_ret=-2; #don't found
leave label_a;
end if;
set out_ret=0;
set out_name=v_name;
set out_age=v_age;
end;
//
delimiter ;
5、c语言调用存储过程
调用方法或步骤:
5.1 、初始化 Mysql 句柄
if(!mysql_init(&mysql))
{
printf("mysql_init failed!/n");
return 0;
}
5.2 、连接到 mysql
//login or connect
if(!mysql_real_connect(&mysql,"localhost","root","","billingdb",0,NULL,CLIENT_MULTI_STATEMENTS))
{
printf("mysql_real_connect() failed!/n");
mysql_close(&mysql);
return 0;
}
5.3 、调用存储过程
//call
strcpy(query,"call querystudent (1,@ret,@out_name,@out_age)");
printf("query sql=[%s]/n",query);
ret= mysql_real_query(&mysql,query,(unsigned int)strlen(query));
5.4 、查询结果集并保存
mysql_query(&mysql, "SELECT @ret,@ out_name,@ out_age ");
//get result
if (ret)
{
printf("Error exec query: %s/n",mysql_error(&mysql));
}
else
{
printf("[%s] exec.../n", query);
}
results = mysql_store_result(&mysql);
5.5 、获取查询结果
while((record = mysql_fetch_row(results))) {
printf("[%s]-[%s]-[%s]/n", record[0], record[1],record[2]);
}
一般存储过程只会有一行的返回结果,^_^.
5.6 、释放资源与 mysql 连接句柄
mysql_free_result(results);
mysql_close(&mysql);
6、结束语
Mysql 存储过程可以实现相当强大的功能,这里只是抛砖引玉的做一些实践,期望能够给大家一些帮助。也欢迎大家交流…
----------------------------------------------------------------------------------------------------------------------------Mysql 存储例程的使用
一、 简介
存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
虽然常用术语是存储过程(stored procedure),但MySQL实际上实现了两中类型,除了存储过程外,还有存储函数(stored routine),它们统称为存储例程。
二、基本格式
1、存储过程
CREATE PROCEDURE 过程名 ([过程参数[,...]])
[特性 ...] 过程体
如创建: CEATE PROCEDURE p1 (a INT)
SELECT a;
调用一下:CALL p1(8);
将显示:
+------+
| a |
+------+
| 8 |
+------+
1 row in set (0.00 sec)
2、存储函数
CREATE FUNCTION 函数名 ([函数参数[,...]])
RETURNS 返回类型
[特性 ...] 函数体
如创建:CREATE FUNCTION f1 (x INT)
RETURNS INT
RETURN x; /* 过程函数一次只能返回一个值
调用一下:SELECT f1 (3);
将显示:
+-------+
| f1(3) |
+-------+
| 3 |
+-------+
1 row in set (0.00 sec)
3、过程参数
[ IN | OUT | INOUT ] 参数名 参数类型
4、函数参数
参数名 参数类型
5、返回类型
有效的MySQL数据类型即可
6、过程体/函数体格式如下
BEGIN
有效的SQL语句
END
7、特性(一般不要求)
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA
}
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
8、存储过程中参数的IN,OUT,INOUT类型
存储过程可以接受输入参数,并把参数返回给调用方。不过,对于每个参数,需要声明其参数名、数据类型,还要指定此参数是用于向过程传递信息,还是从过程传回信息,或是二者兼有。
为声明参数的作用,使用如下3个关键字之一:
IN : IN参数只用来向过程传递信息,为默认值。
OUT : OUT参数只用来从过程传回信息。
INOUT : INOUT参数可以向过程传递信息,如果值改变,则可再从过程外调用。
如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。
对于任何声明为OUT或INOUT的参数,,当调用存储过程时需要在参数名前加上@符号,这样该参数就可以在过程外调用了。
下面举三个实例:MySQL 存储过程 “in” 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible)。
create procedure pr_param_in(
in id int -- in 类型的 MySQL 存储过程参数
)
begin
if (id is not null) then
set id = id + 1;
end if;
select id as id_inner;
end;
set @id = 10;
call pr_param_in(@id);
select @id as id_out;
mysql> call pr_param_in(@id);
+----------+
| id_inner |
+----------+
| 11 |
+----------+
mysql> select @id as id_out;
+--------+
| id_out |
+--------+
| 10 |
+--------+
可以看到:用户变量 @id 传入值为 10,执行存储过程后,在过程内部值为:11(id_inner),但外部变量值依旧为:10(id_out)。
MySQL 存储过程 “out” 参数:从存储过程内部传值给调用者。在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值。
create procedure pr_param_out(
out id int
)
begin
select id as id_inner_1; /* id 初始值为 null*/
if (id is not null) then
set id = id + 1;
select id as id_inner_2;
else
select 1 into id;
end if;
select id as id_inner_3;
end;
set @id = 10;
call pr_param_out(@id);
select @id as id_out;
mysql> set @id = 10;
mysql>
mysql> call pr_param_out(@id); /*外部变量不能传给存储过程*/
+------------+
| id_inner_1 |
+------------+
| NULL |
+------------+
+------------+
| id_inner_3 |
+------------+
| 1 |
+------------+
mysql> select @id as id_out; /*过程将改变的值传给外部变量*/
+--------+
| id_out |
+--------+
| 1 |
+--------+
可以看出,虽然我们设置了用户定义变量 @id 为 10,传递 @id 给存储过程后,在存储过程内部,id 的初始值总是 null(id_inner_1)。最后 id 值(id_out = 1)传回给调用者。
MySQL 存储过程 inout 参数跟 out 类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过inout 参数传递值给存储过程。
drop procedure if exists pr_param_inout;create procedure pr_param_inout
(
inout id int
)
begin
select id as id_inner_1; -- id 值为调用者传进来的值
if (id is not null) then
set id = id + 1;
select id as id_inner_2;
else
select 1 into id;
end if;
select id as id_inner_3;
end;
set @id = 10;
call pr_param_inout(@id);
select @id as id_out;
mysql> set @id = 10;
mysql>
mysql> call pr_param_inout(@id);
+------------+
| id_inner_1 |
+------------+
| 10 |
+------------+
+------------+
| id_inner_2 |
+------------+
| 11 |
+------------+
+------------+
| id_inner_3 |
+------------+
| 11 |
+------------+
mysql>
mysql> select @id as id_out;
+--------+
| id_out |
+--------+
| 11 |
+--------+
从结果可以看出:我们把 @id(10),传给存储过程后,存储过程最后又把计算结果值 11(id_inner_3)传回给调用者。 MySQL 存储过程 inout 参数的行为跟 C 语言函数中的引用传值类似。
通过以上例子:如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。
9、声明和设置变量
(1) 声明变量
在存储例程使用局部变量之前,必须声明局部变量,变量声明通过DECLARE语句实现,其原型如下:
DECLARE variable_name TYPE ;
如:DECLARE x VARCHAR(254);
在声明变量时,声明必须放在BEGIN/END块中。此外声明必须在执行该块任何其它语句之前进行。
(2) 设置变量
SET语句用来设置声明的存储例程变量值。其原型如下:
SET variable_name =value;
如下声明和设置变量过程:
DECLARE x INT;
SET x = 155;
也可使用SELECT…..INTO语句设置变量。
如:
SELECT 155 INTO x;
当然,此变量是声明该变量的BEGIN/END块作用范围内的一个局部变量。如果希望在存储例程外使用此变量,需要将其作为OUT变量传递。
10、执行存储例程
执行存储例程一般是通过CALL和SELECT语句来完成的。
三、多语句存储例程
单语句存储例程非常有用,但存储例程的真正功能在于它能够封装和执行多个SQL语句。
下面介绍创建多语句存储例程时常用的语法。
1、BEGIN和END
当创建多语句存储例程时,需要将语句包围在BEGIN/END块中。
此块的原型如下:
BEGIN
statement 1;
statement 2;
……
statement N;
END
注意,块中每条语句必须以分号结尾。
2、条件语句
IF-ELSEIF-ELSE语句
和C语言中if语句相似。
其原型如下:
IF condition1 THEN
statement1;
ELSEIF condition2 THEN
Statement2;
…….
END IF
CASE语句
需要比较一组可能的值时CASE语句很有用。也是一种条件判断语句。
其原型如下:
CASE
WHEN condition1 THEN statement1;
WHEN condition2 THEN statement2;
………
END CASE;
3、迭代
有些任务需要能够重复地执行一组语句。下面介绍能够迭代执行和退出循环的各种方法。
ITERATE语句
执行ITERATE语句将使嵌入该语句的LOOP、REPEAT或WHILE循环返回顶部,并在此执行。
其原型如下:
ITERATE label
LEAVE语句
在得到变量的值或特定任务的结果后,可能希望通过LEAVE命令立即退出循环或BEGIN/END块。
其原型如下:
LEAVE label
LOOP语句
LOOP语句将不断的迭代处理定义在其代码块中的一组语句,直到遇到LEAVE为止。
其原型如下:
[begin_label:] LOOP
Statement_list
END LOOP [end_label]
REPEAT语句
REPEAT语句在操作上几乎与WHILE相同,很想C语言中的DO….WHERE语句。
其原型如下:
REPEAT
Statement_list
UNTIL condition
END REPEAT
WHILE语句
其原型如下:
WHILE condition DO
Statement_list
END WHILE
下面写一个循环语句的存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `yyw`.`p2` $$
CREATE PROCEDURE `yyw`.`p2` ()
BEGIN
declare v int;
set v=0;
LOOP_LABLE:loop
if v=3 then
set v=v+1;
ITERATE LOOP_LABLE;
end if;
insert into vs values(v); /*将循环值插入数据表vs中*/
set v=v+1;
if v>=5 then
leave LOOP_LABLE;
end if;
end loop;
END $$
DELIMITER ;
四、从另一个例程中调用例程
DELIMITER //
CREATE PROCEDURE p1()
BEGIN
Statement_list
END//
CREATE PROCEDURE p2()
BEGIN
Statement_list
END//
CREATE PROCEDURE p3()
BEGIN
CALL p1();
CALL p2();
END//
注意:直接采用MySQL的Administrator管理器编辑时,可以直接采用函数文本录入;
但若在脚本中自动导入存储过程或函数时,由于MySQL默认以";"为分隔符,则过程体的每一句都被MySQL以存储过程编译,则编译过程会报错;所以要事先用DELIMITER关键字申明当前段分隔符
用完了就把分隔符还原。 如下所示:
DELIMITER $$
Stored Procedures and Functions
DELIMITER ;
五、删除和查看存储例程
1、删除存储例程
要删除存储例程,可以执行DROP语句。
其原型如下:
DROP (PROCEDURE|FUNCTION) P_name;
2、查看例程状态
其原型如下:
SHOW (PROCEDURE|FUNCTION) STATUS LIKE ‘P_name’
如:
SHOW PROCEDURE STATUS LIKE ‘P3’/G;
注意: 使用/G选项以垂直格式显示输出信息。
3、查看例程的创建语法
通过SHOW CREATE语句可以查看创建特定例程所用的语法。
其原型如下;
SHOW CREATE (PROCEDURE|FUNCTION) Db_name.P_name
六、实例
一般在MySQL Query Browser中更方便的创建存储过程及修改内容。
(1)简单的加法运算
DELIMITER $$
DROP PROCEDURE IF EXISTS `yyw`.`p4` $$
CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE `p4`(a int,b int)
BEGIN
declare c int; /*声明的变量
if a is null then /*IF语句
set a = 0;
end if;
if b is null then
set b = 0;
end if;
set c = a + b;
select c as sum; /*结果显示c的值
END $$
DELIMITER ;
调用以下:CALL p4(3,4);
将显示:
+------+
| sum |
+------+
| 7 |
+------+
1 row in set (0.00 sec)
(2)存储过程中的循环语句、数据表数据的导入导出及SQL函数的使用
DELIMITER $$
DROP PROCEDURE IF EXISTS `yyw`.`p4` $$
CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE ‘pro_prime2’(in num int)
BEGIN
declare i,j,x,y int default
0; /*声明变量并默认为0*/
select yywID into j from
text1; /*从数据表txte1中字段yywID的值赋给变量j*/
select 'count
',j; /*显示count字符和j的值*/
while i<num
do /*while……do循环语句*/
set x=2;
pp1:while
x<=sqrt(j) do /*调用内部函数SQRT用于求平方*/
if j%x=0
then /*if循环语句*/
set y=1;
leave pp1;
else
set x=x+1;
end if;
end while;
if y=1 then
set
y=0;
else
set
i=i+1;
insert
into text2 values(j); /*将j的值插入数据表text2*/
end if;
set
j=j+1; /*实现j的自增*/
end while;
END $$
DELIMITER ;
假如原先在数据库中分别建立表text1和text2,text1中有一个字段初始值为3,text2为空;
下面执行一下此存储过程:
mysql> CALL pro_prime2(5);
+--------+------+
| count | j |
+--------+------+
| count | 3 |
+--------+------+
1 row in set (0.00 sec)
mysql> select *from text2;
+-------+
| yywID |
+-------+
| 3 |
| 5 |
| 7 |
| 11 |
| 13 |
+-------+
5 rows in set (0.00 sec)
(3)用存储过程实现计算数据库中某个成绩表总分及平均分,并且调用过程后
能够自动显示基本信息(如学号、姓名、总分、平均分等)。
首先在数据库中建一个成绩表(命名为chengjibiao)如下:
+-----+------+--------+-------+--------+
| NUM | Name | Enlish | Maths | Physis |
+-----+------+--------+-------+--------+
| 1 | 杨业 | 92 |
87 | 96 |
| 2 | 剑锋 | 82 |
98 | 93 |
| 3 | 张美 | 96 |
86 | 94 |
| 4 | 张文 | 76 |
99 | 95 |
| 5 | 叶倩 | 97 |
86 | 88 |
| 6 | 方文 | 87 |
96 | 94 |
| 7 | 李丽 | 97 |
86 | 83 |
| 8 | 贾宇 | 67 |
89 | 77 |
| 9 | 王勃 | 89 |
67 | 75 |
| 10 | 刘三 | 85 |
78 | 95 |
+-----+------+--------+-------+--------+
用SQL语句写存储过程p1
DELIMITER $$
DROP PROCEDURE IF EXISTS `yyw`.`p1` $$
CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE `p1`(N int)
BEGIN
declare a int; /* 变量的声明 */
declare b int;
declare c int;
declare d int;
declare e int;
declare f char(100);
declare g decimal(4,2);
set e=1;
create table zongping (NUM int,Name char(255),Enlish int,Maths int,Physis int,Total int,aver decimal( 4,2)); /* 建一个数据表以存放要显示的内容*/
repeat /* 引进一个REPEAT循环,来计算每位学生总分及平均分*/
select Enlish,Maths,Physis,Name into a,b,c,f from chengjibiao where NUM=e;
/* 导出数据库chengjibiao中的三门成绩及姓名,并把它们分别赋给变量a,b,c,f;*/
set d=a+b+c; /*求和*/
set g=(a+b+c)/3; /*求平均分*/
insert into zongping (NUM,Name,Enlish,Maths,Physis,Total,aver) values (e,f,a,b,c,d,g);
/*将学号,姓名,三门成绩,总分,平均分的数据插入新建的数据表zongping中
set e=e+1; /*该条件可结束循环*/
until e=N /*N是调用存储过程时根据学生数目来设定的*/
end repeat;
select *from zongping; /* 以数据表的形式显示运行结果*/
drop table zongping; /*显示结果后删除表,也可不删*/
END $$
DELIMITER ;
l 调用存储过程
CALL P1 (11); /* 因为原成绩表中有10列数据 ,故设N=11,也可根据不同的成绩表另设
显示结果如下:
+------+------+--------+-------+--------+-------+
| Name | Enlish | Maths | Physis | Total | Aver
|
+------+------+--------+-------+--------+-------+-------+
| 1 | 杨业 | 92
| 87 | 96 |
275 | 91.67 |
| 2 | 剑锋 | 82
| 98 | 93 |
273 | 91.00 |
| 3 | 张美 | 96
| 86 | 94 |
276 | 92.00 |
| 4 | 姜文 | 76
| 99 | 95 |
270 | 90.00 |
| 5 | 叶倩 | 97
| 86 | 88 |
271 | 90.33 |
| 6 | 方文 | 87
| 96 | 94 |
277 | 92.33 |
| 7 | 李丽 | 97
| 86 | 83 |
266 | 88.67 |
| 8 | 贾宇 | 67
| 89 | 77 |
233 | 77.67 |
| 9 | 王勃 | 89
| 67 | 75 |
231 | 77.00 |
| 10 | 刘三 | 85
| 78 | 95 |
258 | 86.00 |
+------+------+--------+-------+--------+-------+-------+
1. 数据库名:test ;
表名:chengjibiao;
字段:Id int , Name char , English int , Maths int , Physis int ;
2. 存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`query` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `query`( in N int, out s char(254) )
BEGIN
declare a,b,c,d,e int;
declare f char(100);
declare g decimal(4,2);
set e=1;
drop table if exists zongping;
create table zongping(NUM int,Name char(255),English int,Maths int,Physis int,Total int,aver decimal(4,2));
repeat
select English,Maths,Physis,Name into a,b,c,f from chengjibiao where Id=e;
set d=a+b+c;
set g=(a+b+c)/3;
insert into zongping(NUM,Name,English,Maths,Physis,Total,aver) values( e,f,a,b,c,d,g );
set e=e+1;
until e=N
end repeat;
select *from zongping as s;
drop table zongping;
END $$
DELIMITER ;
3. 主函数(在文件main.c 中):
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "/usr/include/mysql/mysql.h" #include "/usr/include/mysql/mysql_version.h" #include "/usr/include/mysql/errmsg.h"int main( int argc,char **argv[] ) { MYSQL mysql; MYSQL_ROW results,record; char query[50],s[254]; /** 链接数据库 **/ if(!mysql_init(&mysql)) { printf("mysql_init failed!/n"); return 0; } if(!mysql_real_connect(&mysql,"localhost","root","123456","test",0,NULL,CLIENT_MULTI_STATEMENTS)) { printf("mysql_real_connect() failed!/n"); mysql_close(&mysql); return 0; }
/** 调用存储过程 **/ strcpy(query,"call query(7,@s)"); mysql_real_query(&mysql,query,(unsigned int)strlen(query)); /** 取得存储过程返回值 **/ mysql_query(&mysql, "SELECT @s "); results = mysql_store_result(&mysql);
/** 输出返回值 **/ printf( "Id Name Maths English Physis Total aver/n" ); while((record = mysql_fetch_row(results))) { printf("%1s%10s%8s%12s%11s%10s%10s/n", record[0], record[1],record[2],record[3],record[4],record[5],record[6]); } mysql_free_result(results); mysql_close(&mysql); return 0; }
(编译:gcc -o main main.c -L/usr/lib/mysql/ -lmysqlclient -lz )
4.
成绩表:
+----+-------+-------+---------+--------+
| Id | Name | Maths | English | Physis |
+----+-------+-------+---------+--------+
| 1 | liu | 90 | 80 | 86 |
| 2 | zhang | 88 | 86 | 87 |
| 3 | xiao | 78 | 88 | 98 |
| 4 | wang | 77 | 87 | 97 |
| 5 | li | 79 | 89 | 99 |
| 6 | yi | 67 | 77 | 87 |
运行程序得到的结果:
Id Name Maths English Physis Total aver
1 liu 90 80 86 256 85.33
2 zhang 88 86 87 261 87.00
3 xiao 78 88 98 264 88.00
4 wang 77 87 97 261 87.00
5 li 79 89 99 267 89.00
6 yi 67 77 87 231 77.00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #include "stdio.h" #include "stdlib.h" #include "string.h" #include "/usr/include/mysql/mysql.h" #include "/usr/include/mysql/mysql_version.h" #include "/usr/include/mysql/errmsg.h" int main( int argc,char **argv[] ) { MYSQL my_connection; MYSQL_RES *results; MYSQL_ROW record; MYSQL_FIELD *field; int row, column,i,j; /** 链接数据库 **/ if(!mysql_init(&my_connection)) { printf("mysql_init failed!/n"); return 0; } if(!mysql_real_connect(&my_connection,"localhost","root","123456","yyw",0,NULL,CLIENT_MULTI_STATEMENTS)) { printf("mysql_real_connect() failed!/n"); mysql_close(&my_connection); return 0; }/*这句话是设置查询编码为utf8,这样支持中文*/ mysql_query(&my_connection, "set names utf8"); /** 调用存储过程p1**/ mysql_real_query(&my_connection, "call p1(11)", (unsigned int)strlen("call p1(11)")); /** 取得存储过程返回值 **/ results = mysql_store_result(&my_connection); if (results) { /*取得結果的行数和*/ column = mysql_num_fields(results); row = mysql_num_rows(results) + 1; printf("查询到 %lu 行/n", row); /*输出結果的字段名*/ for (i = 0; field = mysql_fetch_field(results); i++) printf("%s/t", field->name); printf("/n"); /*按行输出結果*/ for (i = 1; i < row; i++) { record = mysql_fetch_row(results); for (j = 0; j < column; j++) printf("%s/t", record[j]); printf("/n"); } } mysql_free_result(results); mysql_close(&my_connection); return 0; }
编辑一下:
[root@localhost home]# gcc -o test test.c -L/usr/lib/mysql/ -lmysqlclient -lz
执行:
[root@localhost home]# ./test
显示:
查询到 10 行
NUM Name Enlish
Maths Physis Total Aver
1 杨业
92 87
96 275
91.67
2 剑锋
82 98
93 273
91.00
3 张美
96 86
94 276
92.00
4 张文
76 99
95 270
90.00
5 叶倩
97 86
88 271
90.33
6 方文
87 96
94 277
92.33
7 李丽
97 86
83 266
88.67
8 贾宇
67 89
77 233
77.67
9 王勃
89 67
75 231
77.00
10 刘三
85 78
95 258
86.00
声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。