Stockage et déclencheurs Linux-MySQL

Un, stockage

PS: La procédure stockée est une fonction importante du stockage de la base de données, mais MySQL ne prend pas en charge la procédure stockée avant la version 5.0, ce qui rend MySQL considérablement réduit dans l'application. Heureusement, MySQL 5.0 a enfin commencé à prendre en charge les procédures stockées, ce qui peut grandement améliorer la vitesse de traitement de la base de données, et en même temps peut également améliorer la flexibilité de la programmation de la base de données.

1. Présentation du stockage

  • Une procédure stockée est un ensemble d'instructions SQL pour exécuter une fonction spécifique. Le but de l'utilisation de procédures stockées est d'écrire des tâches courantes ou complexes à l'avance avec des instructions SQL et de les stocker sous un nom spécifié. Ce processus est compilé, optimisé et stocké dans le serveur de base de données, c'est pourquoi il est appelé procédure stockée. Lorsque vous avez besoin que la base de données fournisse le même service que la procédure stockée définie à l'avenir, il vous suffit d'appeler "CALL stocké le nom de la procédure" pour utiliser la fonction correspondante!
  • L'instruction SQL pour le fonctionnement de la base de données doit être compilée puis exécutée lors de son exécution. La procédure stockée utilise une autre façon d'exécuter des instructions SQL.
  • Une procédure stockée est une fonction programmable, qui est créée et enregistrée dans la base de données, généralement composée d'instructions SQL et de certaines structures de contrôle spéciales! Lorsque vous souhaitez exécuter des fonctions spécifiques correspondantes sur différentes applications ou plates-formes, les procédures stockées deviennent particulièrement adaptées!

2. Avantages de stockage

  • Une fois la procédure stockée encapsulée créée, elle peut être appelée plusieurs fois dans le programme sans avoir à réécrire l'instruction SQL de la procédure stockée, et les professionnels de la base de données peuvent modifier la procédure stockée à tout moment sans affecter l'application qui l'appelle Code source.
  • Peut améliorer la fonction et la flexibilité des instructions SQL. Les procédures stockées peuvent être écrites avec des instructions de contrôle de flux, qui ont une grande flexibilité et peuvent effectuer des jugements complexes et des calculs plus complexes.
  • Peut réduire le trafic réseau. Étant donné que la procédure stockée s'exécute côté serveur et que la vitesse d'exécution est rapide, lorsque la procédure stockée est appelée sur l'ordinateur client, seule l'instruction d'appel est transmise sur le réseau, ce qui peut réduire la charge du réseau.
  • Une fois la procédure stockée hautes performances exécutée une fois, le code binaire généré réside dans la mémoire tampon. Lors des appels suivants, seul le code binaire doit être exécuté à partir de la mémoire tampon, améliorant ainsi l'efficacité et les performances du système.
  • Améliorez la sécurité de la base de données et l'intégrité des données. Utilisez des procédures stockées pour effectuer toutes les opérations de la base de données et vous pouvez contrôler par programme l'accès aux informations de la base de données.

3. Syntaxe de création de procédure stockée

mysql> delimiter ??  #更改其默认的分隔符为“??”,也可以是其他任意符号,只要不是默认的“;”就行
mysql> create  procedure name() #定义存储过程name
    -> begin #存储过程开始
    -> ……  #存放的可以是一些sql语句的集合,当然,它同样有一些判断、循环等语句!!!
    -> end ?? #存储过程结束

mysql> delimiter ;   #更改为默认的分割符,注意中间必须有空格!!!
mysql> call name();  #调用刚才定义的name存储过程

1. Procédures stockées personnalisées

1.1 Insérer d'abord le tableau

mysql> create database cunchu;
Query OK, 1 row affected (0.00 sec)

mysql> use cunchu;
Database changed
mysql> create table roster
    -> (
    -> id int,
    -> name varchar(20),
    -> sex varchar(20),
    -> scores float
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> insert into roster
    -> values 
    -> (1,'张三','男',90.5),
    -> (2,'李四','男',85.5),
    -> (3,'王五','女',78.5),
    -> (4,'刘三','女',66.5),
    -> (5,'赵四','男',50.5);
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from roster;
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    1 | 张三   | 男   |   90.5 |
|    2 | 李四   | 男   |   85.5 |
|    3 | 王五   | 女   |   78.5 |
|    4 | 刘三   | 女   |   66.5 |
|    5 | 赵四   | 男   |   50.5 |
+------+--------+------+--------+
5 rows in set (0.00 sec)

1.2 Ecrire une procédure stockée

L'exemple suivant consiste à afficher toutes les données de la liste! ! !

mysql> delimiter !!
mysql> create procedure test1()
    -> begin
    -> select * from roster;   #查询roster表内容
    -> end !!
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test1();
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    1 | 张三   | 男   |   90.5 |
|    2 | 李四   | 男   |   85.5 |
|    3 | 王五   | 女   |   78.5 |
|    4 | 刘三   | 女   |   66.5 |
|    5 | 赵四   | 男   |   50.5 |
+------+--------+------+--------+
5 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

2. La procédure stockée de l'instruction while

L'exemple suivant montre combien de 1 + 2 + 3 + 4 …… + 100 est égal à! ! !

mysql> delimiter @@  

mysql> create procedure test2()
    -> begin 
    -> declare i int; 			 #定义i为变量名称
    -> declare summary int;  	 #定义summary为变量名称
    -> set i=1;					 #设置变量的初始值为1
    -> set summary=0;			 #设置变量的初始值为0
    -> while i<=100  			 #当i小于或等于100时,执行以下操作
    -> do			 
    -> set summary=summary+i;
    -> set i=i+1;
    -> end while ;				 #循环结束
    -> select summary;			 #查询summary的值
    -> end @@
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test2();
+---------+
| summary |
+---------+
|    5050 |
+---------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

3. Procédure mémorisée de la déclaration de jugement if

L'exemple suivant est de trouver des étudiants masculins dans la liste! ! !

mysql> delimiter @@
mysql> create procedure test3(in t char)
    -> begin
    -> if t="男" then  						 #if语句定义t为男
    -> select * from roster where sex="男";   #查询roster中sex为男
    -> else
    -> select * from roster where sex="女";	 #查询roster中sex为女
    -> end if;  							  #if语句结束
    -> end @@
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test3("男");
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    1 | 张三   | 男   |   90.5 |
|    2 | 李四   | 男   |   85.5 |
|    5 | 赵四   | 男   |   50.5 |
+------+--------+------+--------+
3 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test3("女");
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    3 | 王五   | 女   |   78.5 |
|    4 | 刘三   | 女   |   66.5 |
+------+--------+------+--------+
2 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

4. La procédure stockée de l'instruction case

L'exemple suivant est de trouver les résultats dans la liste! ! !

mysql> delimiter @@
mysql> create procedure test4(in t int)
    -> begin
    -> case t												  
    -> when 1 then
    -> select * from roster where scores>90;                  #查询roster表中scores为大于90
    -> when 2 then
    -> select * from roster where scores>80 and scores<=90;	  #查询roster表中scores为大于80和小于90
    -> when 3 then
    -> select * from roster where scores>60 and scores<=80;	  #查询roster表中scores为大于90和小于80
    -> when 4 then 
    -> select * from roster where scores<60;  				  #查询roster表中scores为小于60
    -> else
    -> select * from roster;								  #查询结果无则执行这条命令
    -> end case;                                         
    -> end @@
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test4(1);
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    1 | 张三   | 男   |   90.5 |
+------+--------+------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test4(2);
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    2 | 李四   | 男   |   85.5 |
+------+--------+------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test4(3);
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    3 | 王五   | 女   |   78.5 |
|    4 | 刘三   | 女   |   66.5 |
+------+--------+------+--------+
2 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test4(4);
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    5 | 赵四   | 男   |   50.5 |
+------+--------+------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test4(5);
+------+--------+------+--------+
| id   | name   | sex  | scores |
+------+--------+------+--------+
|    1 | 张三   | 男   |   90.5 |
|    2 | 李四   | 男   |   85.5 |
|    3 | 王五   | 女   |   78.5 |
|    4 | 刘三   | 女   |   66.5 |
|    5 | 赵四   | 男   |   50.5 |
+------+--------+------+--------+
5 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

5. Modifiez la procédure stockée

grammaire:

mysql> help alter procedure
Name: 'ALTER PROCEDURE'
Description:
Syntax:
ALTER PROCEDURE proc_name [characteristic ...]

characteristic: {
    COMMENT 'string'
  | LANGUAGE SQL
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  #      包含SQL      没有sql   读取SQL数据        修改SQL数据
  | SQL SECURITY { DEFINER | INVOKER }
  #                 定义者  | 调用程序
}

Modifiez la définition de la liste des procédures stockées, modifiez les autorisations de lecture et d'écriture sur MODIFIES SQL DATA et spécifiez que l'appelant peut exécuter

mysql> alter procedure test1  MODIFIES SQL DATA  SQL SECURITY INVOKER;
Query OK, 0 rows affected (0.00 sec)

mysql> show create procedure test1\G;
*************************** 1. row ***************************
           Procedure: test1
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `test1`()
    MODIFIES SQL DATA
    SQL SECURITY INVOKER
begin
select * from roster;
end
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
1 row in set (0.00 sec)

6. Supprimer le stockage

  • Le nom de la procédure spécifie le nom de la procédure stockée à supprimer.
  • IF EXISTS spécifie ce mot clé pour éviter les erreurs causées par la suppression d'une procédure stockée qui n'existe pas. Remarque: Il n'y a pas de liste de paramètres ni de parenthèses après le nom de la procédure stockée. Avant de procéder à la suppression, vous devez confirmer que la procédure stockée n'a pas de dépendances, sinon cela entraînera l'échec de l'exécution des autres procédures stockées qui lui sont associées.
mysql> drop procedure if exists test1;
Query OK, 0 rows affected (0.00 sec)

mysql> call test1();
ERROR 1305 (42000): PROCEDURE cunchu.test1 does not exist

Deuxièmement, le déclencheur

1. Vue d'ensemble

Le déclencheur dans la base de données MySQL est une procédure stockée spéciale. La différence est que l'instruction CALL est utilisée pour appeler la procédure stockée, et l'exécution du déclencheur n'a pas besoin d'être appelée par l'instruction CALL, ni démarré manuellement, tant qu'un événement prédéfini Il sera automatiquement appelé par MySQL si cela se produit.

2. Avantages des déclencheurs

  • L'exécution du programme de déclenchement est automatique et elle est exécutée immédiatement après que les données de la table associée au programme de déclenchement ont été modifiées en conséquence.
  • Le déclencheur peut modifier d'autres tables via la cascade de tables associées dans la base de données.
  • Le programme de déclenchement peut implémenter des contrôles et des opérations plus complexes que les contraintes FOREIGN KEY et CHECK.

3. Le rôle des déclencheurs

Le déclencheur est étroitement lié à la table et est principalement utilisé pour protéger les données de la table. Surtout lorsqu'il existe plusieurs tables avec un certain degré de connexion mutuelle, les déclencheurs peuvent permettre à différentes tables de maintenir la cohérence des données. Le déclencheur ne peut être activé que lors des opérations INSERT, UPDATE et DELETE.

4. Les déclencheurs pris en charge par MySQL sont

Déclencheur INSERT

  • Dans le code de déclenchement INSERT, une table virtuelle nommée NEW (insensible à la casse) peut être référencée pour accéder à la ligne insérée.
  • Dans le déclencheur BEFORE INSERT, la valeur dans NEW peut également être mise à jour, c'est-à-dire que la valeur insérée peut être modifiée (tant qu'elle dispose de l'autorisation d'opération correspondante).
  • Pour la colonne AUTO_INCREMENT, NEW contient la valeur 0 avant l'exécution de INSERT et contiendra la nouvelle valeur générée automatiquement après l'exécution de INSERT.

Déclencheur UPDATE

  • Dans le code de déclenchement UPDATE, une table virtuelle nommée NEW (insensible à la casse) peut être référencée pour accéder à la valeur mise à jour.
  • Dans le code de déclenchement UPDATE, une table virtuelle nommée OLD (insensible à la casse) peut être référencée pour accéder à la valeur avant que l'instruction UPDATE ne soit exécutée.
  • Dans un déclencheur BEFORE UPDATE, la valeur de NEW peut également être mise à jour, c'est-à-dire qu'il est autorisé à modifier la valeur à utiliser dans l'instruction UPDATE (tant qu'elle dispose de l'autorité d'opération correspondante). Les valeurs dans OLD sont toutes en lecture seule et ne peuvent pas être mises à jour. Remarque: Lorsque le déclencheur est conçu pour déclencher l'opération de mise à jour de la table elle-même, seuls les déclencheurs de type BEFORE peuvent être utilisés, les déclencheurs de type AFTER ne seront pas autorisés.

DELETE trigger

  • Dans le code de déclenchement DELETE, vous pouvez faire référence à une table virtuelle nommée OLD (insensible à la casse) pour accéder aux lignes supprimées. Les valeurs dans OLD sont toutes en lecture seule et ne peuvent pas être mises à jour.

5. Dans le processus d'utilisation du déclencheur, MySQL gérera les erreurs de la manière suivante

  • Pour les tables transactionnelles, si le déclencheur échoue et que l'instruction entière qui en résulte échoue, toutes les modifications effectuées par l'instruction seront annulées; pour les tables non transactionnelles, cette annulation ne peut pas être effectuée, même si l'instruction échoue, Toutes les modifications effectuées avant le l'échec sont toujours valides.
  • Si le déclencheur BEFORE échoue, MySQL n'effectuera pas l'opération sur la ligne correspondante.
  • Si une erreur se produit pendant l'exécution du programme de déclenchement BEFORE ou AFTER, l'instruction entière qui appelle le programme de déclenchement échouera.
  • Uniquement lorsque le déclencheur BEFORE et l'opération de ligne ont été exécutés avec succès, MySQL exécutera le déclencheur AFTER.

Créer une syntaxe de déclenchement:

Voir aide

mysql> help create trigger
Name: 'CREATE TRIGGER'
Description:
Syntax:
CREATE
    [DEFINER = user]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    [trigger_order]
    trigger_body

trigger_time: { BEFORE | AFTER }
 #                 之前 | 之后
trigger_event: { INSERT | UPDATE | DELETE }

trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

grammaire:

mysql> delimiter $$           #更改其默认的分隔符为“$$”,也可以是其他任意符号,只要不是默认的“;”就行
mysql> create trigger test    #为触发器定义名字为test
    -> after insert           #选择after
    -> on 表名 for each row
    -> begin                  #开启
    -> ……                     #自定义sql语句
    -> end $$				  #结束
    
mysql> delimiter ;			  #更改为默认的分割符,注意中间必须有空格!!!	

1. Créez un tableau et insérez des données

mysql> create table goods
    -> ( 
    -> g_id int,
    -> g_name varchar(30),
    -> quantity int 
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql> create table orders 
    -> (
    -> o_id int ,
    -> g_id int,
    -> counts int,
    -> price int
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into goods
    -> values 
    -> (1,'apple','100'),
    -> (2,'banana','100'),
    -> (3,'pineapple','100');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |      100 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

2. Insérer une déclaration

L'exemple suivant montre que la table d'inventaire soustrait automatiquement le produit correspondant une fois le produit vendu! ! !

mysql> delimiter $$ 
mysql> create trigger test5
    -> after insert 
    -> on orders for each row
    -> begin
    -> update goods set quantity=quantity-new.counts where g_id=new.g_id;
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

#查看原先数据
mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |      100 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

#插入数据
mysql> insert into orders values(1,2,10,55);
Query OK, 1 row affected (0.00 sec)

#查看插入之后的对应数据是否对应
mysql> select * from orders;
+------+------+--------+-------+
| o_id | g_id | counts | price |
+------+------+--------+-------+
|    1 |    2 |     10 |    55 |
+------+------+--------+-------+
1 row in set (0.00 sec)

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |       90 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

3. mise à jour de la déclaration

mysql> delimiter $$
mysql> create trigger test6
    -> after update 
    -> on orders for each row
    -> begin
    -> update goods set quantity=quantity-(new.counts-old.counts) where g_id=new.g_id;
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

3.2 Augmentation

Ce qui suit est pour les clients, la commande augmente, le tableau d'inventaire change automatiquement! ! !

#查看俩个表的数据
mysql> select * from goods;    
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |       90 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from orders;
+------+------+--------+-------+
| o_id | g_id | counts | price |
+------+------+--------+-------+
|    1 |    2 |     10 |    55 |
+------+------+--------+-------+
1 row in set (0.00 sec)

#更新数据
mysql> update orders set counts=20 where o_id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#查看更新之后的俩表的数据
mysql> select * from orders;
+------+------+--------+-------+
| o_id | g_id | counts | price |
+------+------+--------+-------+
|    1 |    2 |     20 |    55 |
+------+------+--------+-------+
1 row in set (0.00 sec)

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |       80 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

3.3 Réduire

Ce qui suit montre que le stock changera automatiquement en données en temps réel après le retour du client! ! !

#更改数据
mysql> update orders set counts =5 where o_id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#查看更改之后的数据
mysql> select * from orders;
+------+------+--------+-------+
| o_id | g_id | counts | price |
+------+------+--------+-------+
|    1 |    2 |      5 |    55 |
+------+------+--------+-------+
1 row in set (0.00 sec)

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |       95 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

4. supprimer la déclaration

Voici les données correspondant à la conversion automatique dans le tableau après le retour du client! ! !

mysql> delimiter $$
mysql> create trigger test7
    -> after delete
    -> on orders for each row 
    -> begin
    -> update goods set quantity=quantity+old.counts where g_id=old.g_id;
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

#查看原先数据
mysql> select * from orders;
+------+------+--------+-------+
| o_id | g_id | counts | price |
+------+------+--------+-------+
|    1 |    2 |      5 |    55 |
+------+------+--------+-------+
1 row in set (0.00 sec)

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |       95 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

#删除出货表的数据
mysql> delete from orders where o_id =1;
Query OK, 1 row affected (0.01 sec)

#查看删除之后的对应数据
mysql> select * from orders;
Empty set (0.00 sec)

mysql> select * from goods;
+------+-----------+----------+
| g_id | g_name    | quantity |
+------+-----------+----------+
|    1 | apple     |      100 |
|    2 | banana    |      100 |
|    3 | pineapple |      100 |
+------+-----------+----------+
3 rows in set (0.00 sec)

5. Supprimer le déclencheur

#查看触发器
mysql> show create trigger test7\G
*************************** 1. row ***************************
               Trigger: test7
              sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
SQL Original Statement: CREATE DEFINER=`root`@`localhost` trigger test7
after delete
on orders for each row 
begin
update goods set quantity=quantity+old.counts where g_id=old.g_id;

end
  character_set_client: utf8
  collation_connection: utf8_general_ci
    Database Collation: utf8_general_ci
               Created: 2020-12-27 20:40:01.82
1 row in set (0.00 sec)

#删除触发器
mysql> drop trigger test7;
Query OK, 0 rows affected (0.00 sec)

mysql> show create trigger test7\G
ERROR 1360 (HY000): Trigger does not exist

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45191791/article/details/112251721
conseillé
Classement