MySQL中的存储过程、函数与触发器

一.对待存储过程和函数的态度

优点:
1.存储过程只在创建时进行编译,sql语句则每次执行都需要编译。能提高数据库执行速度。
2.简单复杂操作结合事物一起封装。
3.复用性高。
4.安全性高,可指定存储过程的使用权。

实际项目中应该尽量少用存储过程和函数,理由如下:

1.移植性差,在MySQL中的存储过程移植到sqlsever上就不一定可以用了。

2.调试麻烦,在db中报一个错误和在应用层报一个错误不是一个概念,那将是毁灭性打击,直接一个error:1045什么的更本毫无头绪。

3.扩展性不高

所以在互联网时代大型项目应该尽量少使用(不使用)存储过程和函数。

二.创建存储过程

2.1什么是存储过程?

存储过程和存储函数都是一组sql语句的集合。这些语句集合被当做一个整体存入数据库中。

2.2创建存储过程的语法:

create procedure 存储过程名(参数列表)

                    sql语句

例子:

delimiter //
create procedure pro()
reads sql data
begin
select * from stu;
end

那么我们现在就有一个存储过程pro了,但是这个存储过程他是没有参数的,他只是执行一次查询操作。

我们现在来讲解一下这个存储过程的结构:

delimiter //  是将分号转化为//   因为在sql执行时当他遇到分号 ; 时他就讲停止所以我们必须将其转化为 //直到最后一行才会停止执行。

reads sql  data   解释characteristic的状态在这里是只读模式,其他的模式还有:no sql 没有sql语句 , ins  sql 不包含读和写的语句 , modifies sql data   包含写入数据的语句等等。

begin /***/  end   在存储过程中当有多条语句集合时我们必须使用begin和end

//   结束整个存储过程

2.3使用存储过程

在只是创建了一个存储过程,那么我们怎么来使用这个存储过程呢?

语法:call  存储过程名()

将上一个存储过程pro使用的例子:

call pro();

 

2.4创建一个带参数的存储过程

参数列表:存储过程的参数有三种类型:in,out,inout 分别表示传入参数和传出参数,和即传入也传出参数。

例子:首先我们来创建两张表:课程表是学生表的从表

create table stu(
stu_id bigint primary key auto_increment,#学号
stu_name varchar(10) not null,#姓名
stu_major int not null,#专业号
stu_sex char,#性别
stu_in date,#入学日期
stu_birth date,#出生日期
foreign key (stu_major) references major(ma_id)#专业外键设置
);

create table major(
ma_id int primary key,
ma_name varchar(15), 
Ma_boss VARCHAR ( 10 ) 
); 
INSERT  INTO Major values ( . 1 , "Information Management", "Joe Smith");
 INSERT  INTO Major values ( 2 , "e-commerce", "John Doe");
 INSERT  INTO STU values ( . 1 "Bob", 1 , "M", " 2017 - 09 - 01 " " 1998 - 12 is - 23 is ");
 INSERT  INTO STU values ( 2 , "small high",1,"男","2017-09-01","1998-05-01");
insert into stu values(3,"小李",2,"男","2017-09-01","1999-04-01");

 

Let's create a stored procedure with parameters to find the name of the student's majors, the code is as follows:

delimiter //
create procedure pro1(in sname varchar(10),out ma varchar(10))
reads sql data
begin
select ma_name into ma from major where ma_id = (select stu_major from stu where stu_name=sname);
end
//

Using this stored procedure: code is as follows:

the SET  @ma = "no inquiry before"; 
Call Pro1 ( "Li", @ma );
 the SELECT  @ma ;

The results are as follows:

Explain the code: the first to use set @ma define a global variable, and then use call the stored procedure name  syntax to call a stored procedure, while the value of the global variable ma also changed.

III. Creating a memory function

3.1 Different stored procedures and stored functions.

1. In return function, the return value must be

2. In the stored procedure parameters in out inout are three default in type, but in only one function in type.

3.2 Creating a function

Syntax: the Create function function name ()

         return return type

          sql statement collection

example:

delimiter //
create function fun1(num int)
returns int
begin
return num+1000;
end
//

The biggest difference between functions and stored procedures that return is obviously

3.3 calling function

Syntax not use the keyword call, but the keyword the SELECT, the SELECT function name

example:

select fun1(100);

result:

 

IV. Delete stored functions and stored procedures

 Syntax: drop Procedure | function stored procedure name or function name

 example:

drop procedure pro;

 Note that he is without parentheses

 

V. Using cursors during storage and storage functions

5.1 Why do you need a cursor?

When we might use multiple data when using stored procedures, then we need to use the cursor to store a plurality of data.

5.2 Use the cursor Note points

The cursor can not exist alone, it must be used during storage or storage function.

5.3 Use the cursor

grammar:

1. Create a cursor: DECLARE cursor-name cursor for select statement  

2. Open the cursor: Open cursor name

3. Use the cursor: FETCH Cursor name into a variable name

4. Close the cursor: Close cursor name

5.4 Examples

delimiter //
create function fun3(id int)
returns int
reads sql data
begin
declare cur cursor for select stu_id from stu;
open cur;
fetch cur into id;
close cur;
return id;
end
//

 use

set @id=0;
select fun3(@id);

 

 

 result

The cursor can be found in just the first value to the variable.

 

Sixth, what is the trigger

Triggers are database objects associated with a table, while meeting the definition of trigger conditions, trigger and execute the statement as defined in the collection. This feature can help trigger the application on the database side to ensure data integrity.

For example, you now have two tables such as user tables [] and [] log table, when a user is created, you need to insert log log is created in the log table, if without the use of triggers in you need to write programming language logic to achieve, but if you define a flip-flop, flip-flop effect is that when you insert a data in the user table to help you insert a log message in the log table. Of course, the flip-flop is not only the insertion operation, but also to perform the modification, deletion.

Creating Triggers

Create trigger syntax is as follows:

Copy the code
TRIGGER ON trigger_name trigger_time trigger_event the CREATE tb_name the FOR EACH ROW trigger_stmt 
trigger_name: name of the trigger 
tirgger_time: Trigger timing for BEFORE or an AFTER 
trigger_event: the triggering event for the INSERT, DELETE, or UPDATE 
tb_name: REPRESENTATION trigger indicates that is where Zhang establish a trigger on the table 
trigger_stmt: procedure body triggers, can be a SQL statement or multiple statements with BEGIN and END contained in 
it can be said to create MySQL trigger the following six: 
the BEFORE INSERT, the BEFORE DELETE, the BEFORE UPDATE 
an AFTER INSERT , AFTER DELETE, AFTER UPDATE
Copy the code

Among them, the trigger trigger name parameter refers to the creation of the name

BEFORE and AFTER trigger parameter specifies the time of execution, before or after the event

FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器

创建有多个执行语句的触发器
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
    执行语句列表
END

其中,BEGIN与END之间的执行语句列表参数表示需要执行的多个语句,不同语句用分号隔开

tips:一般情况下,mysql默认是以 ; 作为结束执行语句,与触发器中需要的分行起冲突

     为解决此问题可用DELIMITER,如:DELIMITER ||,可以将结束符号变成||

     当触发器创建完成后,可以用DELIMITER ;来将结束符号变成;

Copy the code
mysql> DELIMITER ||
mysql> CREATE TRIGGER demo BEFORE DELETE
    -> ON users FOR EACH ROW
    -> BEGIN
    -> INSERT INTO logs VALUES(NOW());
    -> INSERT INTO logs VALUES(NOW());
    -> END
    -> ||
Query OK, 0 rows affected (0.06 sec)

mysql> DELIMITER ;
Copy the code

上面的语句中,开头将结束符号定义为||,中间定义一个触发器,一旦有满足条件的删除操作

就会执行BEGIN和END中的语句,接着使用||结束

Finally, use DELIMITER; reduction will end symbol

tigger_event:

 

load data statement is the contents of the file into the table, equivalent to the insert statement, but replace the statement and insert almost under normal circumstances, but when if there is primary or unique index table, if the inserted data and the original primary key or unique the same time, it will delete the original data, and then add a new data, so sometimes perform a replace statement is executed as a delete and insert statements.

Triggers can be a SQL statement, it can be more than one SQL code block, then how to create it?

Copy the code
DELIMITER $ # the statement separator to $ 
BEGIN 
SQL1; 
SQL2; 
... 
sqln 
END $ 
DELIMITER; # the statement delimiter back to the original semicolon ";"
Copy the code

In the BEGIN ... END statement can also define variables, but can only be used within BEGIN ... END:

DECLARE var_name var_type [DEFAULT value] # define a tag, to specify default values 
SET var_name = value # variable assignment

NEW and OLD use:

 

 According to the above table, it can be used with the appropriate data format:

NEW.columnname: a new column data rows 
in a column of data rows to be deleted: OLD.columnname

Having said that we are now to create a trigger bar!

There are the following table:
User users table

Copy the code
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
  `add_time` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`(250)) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1;
Copy the code

Log logs table:

TABLE `logs` the CREATE ( 
  ` Id` int (. 11) the AUTO_INCREMENT the NOT NULL, 
  `log` VARCHAR (255) the COMMENT the DEFAULT NULL 'described log', 
  a PRIMARY KEY (` Id`) 
) ENGINE the InnoDB the DEFAULT the CHARSET = = = utf8mb4 the COMMENT ' log table ';

Demand is: when users insert a data in a log information is generated logs.

Creating triggers:

Copy the code
DELIMITER $ 
the CREATE TRIGGER USER_LOG an AFTER the INSERT the ON Users the FOR EACH the ROW 
the BEGIN 
the DECLARE S1 VARCHAR (40) Character SET UTF8; 
the DECLARE S2 VARCHAR (20 is) Character SET UTF8; back # found Chinese character encoding garbled, where the character set 
SET s2 = " Created IS "; 
the SET CONCAT S1 = (NEW.name, S2); # CONCAT function string can be connected to 
the INSERT the INTO logs (log) values (S1); 
the END $ 
DELIMITER;
Copy the code

Here I use navicat: 

View Trigger

SHOW TRIGGERS statement Viewing Trigger Information

Tip:

I use the above navicat created directly, if you use the mysql front, name there will be a difference, we just delete the trigger in Mysql front in test
drop trigger user_log; # delete trigger

Open Mysql Front:

 

When compiling mysql front sql, do not define the end delimiter, sql directly modified so that can:

Copy the code
#DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2);     #函数CONCAT可以将字符串连接
INSERT INTO logs(log) values(s1);
END #$
#DELIMITER ;
Copy the code

这里再啰嗦几句:

tips:SHOW TRIGGERS语句无法查询指定的触发器

在triggers表中查看触发器信息
SELECT * FROM information_schema.triggers;

结果显示了所有触发器的详细信息,同时,该方法可以查询制定触发器的详细信息

SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME='user_log';

tips:所有触发器信息都存储在information_schema数据库下的triggers表中

     可以使用SELECT语句查询,如果触发器信息过多,最好通过TRIGGER_NAME字段指定查询

回到上面,我们创建好了触发器,继续在users中插入数据并查看数据:

insert into users(name,add_time) values('周伯通',now());

Well, let's look at the logs table now!

By the example above, you can see only information the user needs to be inserted in the users, the log will be automatically recorded in the logs table, maybe that is the trigger for me to bring the convenience of it!

 

Restrictions and precautions

Will trigger the following two restrictions:

1. The trigger can not call to return data stored program client can not be used using the CALL statement dynamic SQL statements, but allows a program stored data to return trigger parameter, which is stored procedure or function by OUT or INOUT type parameters the data returned trigger is possible, but the process can not be called directly return data.

2. The trigger can not be used to display a sentence beginning or end of a transaction or implicit manner, such as START TRANS-ACTION, COMMIT, or ROLLBACK.

Note: MySQL triggers accordance BEFORE trigger, line operations, AFTER triggers the order of execution, in which the error occurred will not be any step to continue the rest of the operation, the operation if the transaction table, and if there is an error , it will be rolled back, if for non-transactional table operation, then it can not be rolled back, and the data may be wrong.

 

 Original Source:

https://www.cnblogs.com/SAM-CJM/p/9711458.html

https://www.cnblogs.com/phpper/p/7587031.html

 

Guess you like

Origin www.cnblogs.com/ryelqy/p/11425012.html