公司要建立网站要怎么做,合肥建设云平台证书查询,wordpress添加原文链接,嘉兴建设网站的mysql数据库存储过程及调用方法 mysql5.0以后就支持存储过程了#xff0c;目前mysql的6.0Alpha版也已经推出。6.0不仅支持大型数据库如oracle等的绝大部分功 能#xff0c;如存储过程、视图、触发器、job等等#xff0c;而且修正了这些功能所存在的bug#xff0c;其中6.0.1…mysql数据库存储过程及调用方法 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_id0) then
set out_ret-1; #id error
leave label_a; end if; SELECT name,age into v_name,v_age from student where idin_id limit 1; if v_age is NULL then
set out_ret-2; #dont found
leave label_a; end if; set out_ret0; set out_namev_name; set out_agev_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执行存储过程后在过程内部值为11id_inner但外部变量值依旧为10id_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 的初始值总是 nullid_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 |
--------
从结果可以看出我们把 id10传给存储过程后存储过程最后又把计算结果值 11id_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 v0; LOOP_LABLE:loop if v3 then set vv1; ITERATE LOOP_LABLE; end if; insert into vs values(v); /*将循环值插入数据表vs中*/ set vv1; if v5 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 DEFINERyang10.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 DEFINERyang10.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 inum do /*while……do循环语句*/ set x2; pp1:while xsqrt(j) do /*调用内部函数SQRT用于求平方*/
if j%x0 then /*if循环语句*/
set y1;
leave pp1;
else
set xx1;
end if; end while; if y1 then set y0; else set ii1; insert into text2 values(j); /*将j的值插入数据表text2*/ end if; set jj1; /*实现j的自增*/ end while; END $$
DELIMITER ;
假如原先在数据库中分别建立表text1和text2text1中有一个字段初始值为3text2为空
下面执行一下此存储过程
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 DEFINERyang10.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 e1;
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 NUMe;
/* 导出数据库chengjibiao中的三门成绩及姓名并把它们分别赋给变量a,b,c,f;*/
set dabc; /*求和*/
set g(abc)/3; /*求平均分*/
insert into zongping (NUM,Name,Enlish,Maths,Physis,Total,aver) values (e,f,a,b,c,d,g); /*将学号姓名三门成绩总分平均分的数据插入新建的数据表zongping中
set ee1; /*该条件可结束循环*/
until eN /*N是调用存储过程时根据学生数目来设定的*/
end repeat; select *from zongping; /* 以数据表的形式显示运行结果*/ drop table zongping; /*显示结果后删除表也可不删*/
END $$
DELIMITER ; l 调用存储过程
CALL P1 (11); /* 因为原成绩表中有10列数据 故设N11也可根据不同的成绩表另设 显示结果如下 ------------------------------------------ | 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 DEFINERrootlocalhost 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 e1; 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 Ide; set dabc; set g(abc)/3; insert into zongping(NUM,Name,English,Maths,Physis,Total,aver) values( e,f,a,b,c,d,g ); set ee1; until eN 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; }
编辑一下
[rootlocalhost home]# gcc -o test test.c -L/usr/lib/mysql/ -lmysqlclient -lz
执行
[rootlocalhost 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