SQL存储过程, since 2021-12-19

(2021.12.19 Sat)
SQL语句需要先编译再执行,存储过程(stored procedure)是完成了特定功能的SQL语句集合,经过编译保存在数据库中。用户可以通过名字调用和执行存储过程,并可以传递参数,和返回数据。

存储过程是可编程的函数,可以简单理解为是在数据库中实现的面向对象中的方法。

创建存储过程

创建过程伪代码

CREATE PROCEDURE ([[IN | OUT | INOUT] arg_name arg_type[, arg_name1 arg_type1])
BEGIN
        
        
END

对于MySQL,还需要加入DELIMITER关键词

DELIMITER &&
CREATE PROCEDURE ([[IN | OUT | INOUT] arg_name arg_type[, arg_name1 arg_type1])
BEGIN
        
        
END &&
DELIMITER;

说明:

  • procedure_name: 过程名
  • IN | OUT | OUTIN: 参数传递方式,IN表示调用者向过程传入的参数,OUT表示过程返回给调用者的参数/结果,OUTIN表示向过程传递变量也从过程返回变量。
  • arg_name & arg_type:传入或传出的变量名与类型
  • BEGIN...END:过程主体
  • declaration_section:主体的声明变量部分
  • execution_section:函数执行部分代码

声明部分

声明部分的格式如下

DECLARE [DEFAULT ];

DECLARE net_pay FLOAT(9,2) DEFAULT 0;
DECLARE id_name INT DEFAULT 0;
DECLARE dt DATETIME DEFAULT '2021-12-19 11:41:30';
DECLARE vv VARCHAR(255) DEFAULT 'This is a stored procedure demo.';

执行部分格式

执行部分即SQL的指令。除了常规的SQL命令,可使用IF-ELSECASE-WHENWHILE-DOREPEAT-UNTIL-ENDLOOP-END语句。这些循环或判断结构可结合LEAVE指令用来结束结构。同时注意到,BEGIN-END结构可以嵌套。

BEGIN-END结构可以被贴标签。

label_1: BEGIN
           DECLARE var1 int DEFAULT 0;
           SELECT var1;
END label_1;

判断和循环语句的格式

WHILE-DO...END-WHILE

DELIMITER //
CREATE PROCEDURE proc1 ()
     BEGIN
          DECLEAR var INT;
          SET var = 7;
          WHILE var < 6 DO
               INSERT INTO specific_table VALUES (var);
               SET var = var + 1;
          END WHILE;
     END;
//
DELIMITER;

REPEAT...UNTIL...END REPEAT,该命令与WHILE不同的是先运行,后检查运行条件。

DELIMITER //
CREATE PROCEDURE proc2 ()
     BEGIN
          DECLEAR var INT;
          SET var = 5;
          REPEAT 
               INSERT INTO specific_table VALUE (var);
               SET var = 6;
               UNTIL var >= 7;
           END REPEAT;
     END;
//
DELIMITER;

LOOP

DELIMITER//
CREATE PROCEDURE proc ()
     BEGIN
          DECLEAR var INT;
          SET var = 4;
          loop_label: LOOP
               INSERT INTO specific_table VALUES (var);
               SET var = var + 1;
               IF var >= 6
                    LEAVE loop_label;
               END IF;
          END LOOP;
     END;
//
DELIMITER

IF-ELSE-THEN语句

DELIMITER //
CREATE PROCEDURE proc (IN para INT)
     BEGIN
          DECLEAR var INT;
          SET var = para + 6;
          IF para > 0 THEN
               INSERT INTO specific_table VALUES (var);
          ELSE
               INSERT INTO specific_table VALUES (var-para);
          END IF;
     END;
//
DELIMITER;

CASE-WHEN-THEN-ELSE语句

DELIMITER //
CREATE PROCEDURE proc4 (IN parameter INT)
     BEGIN
          DECLARE var INT;
          SET var=parameter+1;
          CASE var
          WHEN 0 THEN
               INSERT INTO t VALUES (17);
          WHEN 1 THEN
               INSERT INTO t VALUES (18);
          ELSE
               INSERT INTO t VALUES (19);
          END CASE ;
     END ;
//
DELIMITER ;

ITERATE迭代通过引用复合语句的label,来从新开始复合语句。

#ITERATE
DELIMITER //
  CREATE PROCEDURE proc()
  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 t VALUES(v);
      SET v=v+1;
      IF v>=5 THEN
        LEAVE LOOP_LABLE;
      END IF;
    END LOOP;
  END;
  //
DELIMITER ;

变量作用域

分隔符DELIMITER

注意DELIMITER//DELIMITER;两句,MySQL默认以";"为分隔 符,如果没有声明分割符,编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字声明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。

调用存储过程

在mysql console中调用格式如下

mysql -> CALL proc_name();

如果调用时需要传入参数或传出参数,需要提前声明,注意在console中变量名前需要加@
变量赋值部分的格式如下

SET @ = ;
or
SELECT INTO @;

SET @var = 100; // 赋值
SELECT 'this is a test string' INTO @char_var;
SELECT @var; // 选定和返回数值变量
SELECT @char_var; // 选定和返回字符变量

注意,在存储过程的执行部分调用时不需要@符号,直接使用变量名即可。在mysql console需要有@标识符。

mysql -> SET @var = 1;
mysql -> CALL proc_name(@var);

存储过程的查询

SELECT name FROM mysql.proc WHERE db = ;
SELECT routine_name FROM information_schema.routines WHERE routine_schema = ;
SHOW PROCEDURE STATUS WHERE db = ;

#查看存储过程详细信息
SHOW CREATE PROCEDURE 数据库.存储过程名;

存储过程的修改和删除

ALTER PROCEDURE 更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic:
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'

变量解释:

  • sp_name参数表示存储过程或函数的名称;
  • characteristic参数指定存储函数的特性。
  • CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
  • NO SQL表示子程序中不包含SQL语句;
  • READS SQL DATA表示子程序中包含读数据的语句;
  • MODIFIES SQL DATA表示子程序中包含写数据的语句。
  • SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,* DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
    COMMENT 'string'是注释信息。

删除

DROP PROCEDURE [proc_name1[, proc_name2...]];

你可能感兴趣的:(SQL存储过程, since 2021-12-19)