MySQL存储过程语法基础

图片还没有哦

由于博主水平有限 下面语法记录有不对还请留下你珍贵的意见

mysql的基础数据类型

名称 类型 说明
INT 整型 4字节整数类型,范围约+/-21亿
BIGINT 长整型 8字节整数类型,范围约+/-922亿亿
REAL 浮点型 4字节浮点数,范围约+/-1038
DOUBLE 浮点型 8字节浮点数,范围约+/-10308
DECIMAL (M,N)高精度小数 由用户指定精度的小数,例如,DECIMAL(20,10)表示一共20位,其中小数10位,通常用于财务计算
CHAR(N) 定长字符串 存储指定长度的字符串,例如,CHAR(100)总是存储100个字符的字符串
VARCHAR(N) 变长字符串 存储可变长度的字符串,例如,VARCHAR(100)可以存储0~100个字符的字符串
BOOLEAN 布尔类型 存储True或者False
DATE 日期类型 存储日期,例如,2018-06-22
TIME 时间类型 存储时间,例如,12:20:59
DATETIME 日期和时间类型 存储日期+时间,例如,2018-06-22 12:20:59

基础关键语法

1
2
3
4
5
6
7
8
   DELIMITER --  声明语句结束符,用于区分;
DECLARE n_sid INT ; -- 使用了 DECLARE 声明出来的变量 要用 into 进行赋值 下面就是一个例子 把 t_span_rank_babao_furnace 表中查到 的a_sid 赋值给 n_sid
select a_sid into n_sid from t_span_rank_babao_furnace where sid = _sid;

CEATE PROCEDURE demo_in_parameter(IN p_in int) -- 声明创建存储过程
BEGIN …. END -- 存储过程开始和结束符号
SET @p_in=1 -- 变量赋值
DECLARE l_int INT DEFAULT 4000000; -- 变量定义(默认值为4000000) 这里要注意 变量类型在最后哦 习惯了c或其他语言可能会不习惯

ps:在写sql存储过程的时候sql的关键字尽量都用大写

存储过程与各种变量

参考

局部变量

局部变量只在BEGIN … END 代码块中有效,执行完代码块变量就会消失,在存储过程中最为常见的变量 DELIMITER是专门用来定义局部变量的可以使用DEFAULT来指定变量的默认值
DELIMITER x,y INT DEFAULT 100; 定义了INT类型的变量x,y 并且赋予默认值为100 赋值用SET 或 SELECT
赋值例:
SELECT … INTO 语句 这个SELECT语法把选定的值直接存储到变量

1
2
3
4
5
6
7
8
9
10
11
12
DECLARE total_count INT DEFAULT 0; -- 定义了INT类型变量total_count 默认值给予0
SET total_count = 10; -- 把10赋值给INT类型变量total_count
SELECT COUNT(*) INTO total_count FROM products; -- COUNT(*) 查找products表中的行数 把他赋值给total_count

DELIMITER $$
CREATE PROCEDURE p1(IN a INT,IN b INT)
BEGIN
DECLARE c INT DEFAULT 0; -- 定义一个INT类型的变量c 默认值为0
SET c = a + b;
SELECT c AS num; -- 为c取'别名'
END;$$
DELIMITER;

总结:这里的c就是局部变量

SQL语法中AS中的作用及用法

用户变量

用户变量与数据库的连接有关(一个客户端定义的变量不能被其他客户端使用)当客户端连接断开退出时,该客户端的变量将全部失效。用户变量不需要声明,可以直接使用,定义用户变量时变量名前必须要加@。
赋值例(一般用SET):

1
2
SET @varName = value;
SELECT @var_name := value;

注1:”=”是比较操作符,判断两边参数是否相等,或者在更新语句中进行赋值
注2:“:=”主要是用于传递外部参数为语句中变量赋值
注3:赋值后输出用:SELECT @varName
注4:@c=@b*2是正确的,@b=@b+1是错误的,但SET @b=@b+1是正确的,这一点不像C++

系统变量

mysql可以访问许多系统变量。当服务器运行时许多变量允许动态更改,这样就可以在不重启服务器就可以完成更新了。系统变量又包含两种:会话变量(影响具体客户端连接操作),全局变量(影响服务器整体操作)

全局变量

全局变量在mysql启动的时候由服务器初始化他们的值,这些默认值可以在/etc/my.cnf中修改。想要更改全局变量的值需要SUPER权限。全局变量作用域SERVER的生命周期,当服务器重启后所有全局变量值都失效,要想要全局变量在重启后生效,需要更改相应的配置文件
查看全局变量例:

1
2
SHOW GLOBAL variables; -- 变量太多,一般不用
SHOW GLOBAL variables like `搜索条件`;

修改全局变量例:

1
2
SET GLOBAL varname = value;
SET @@GLOBAL.varname = value;

会话变量

会话变量在每个数据库连接建立后,有mysql来初始化。mysql会将当前所有的全局变量都复制一份作为会话变量,相当于在建立会话之后,如果没有更改过会话变量与全局变量的值,那么这两份变量的值是完全一致的。设置会话变量不需要特殊权限,会话变量的作用域与用户变量一样,仅限于当前连接客户端。
查看会话变量例:

1
2
SHOW SESSION variables; -- 变量太多,一般不用
SHOW variables like `搜索条件`;

修改会话变量例:

1
2
SET SESSION varname = value; -- 变量太多,一般不用
SET @@SESSION.varname = value;

SESSION关键字,都可以用LOCAL关键字来代替。

创建存储过程

CREATE PROCEDURE proc_first 不带参数
BEGIN
    ...sql语句
END

CREATE PROCEDURE proc_first(OUT p INT) 带参数
BEGIN
    ...sql语句
END

下面是存储过程的例子:

1
2
3
4
5
6
7
8
9
DELIMITER $$
CREATE PROCEDURE proc1(OUT s INT)
BEGIN
SELECT COUNT(*) INTO s FROM user;
END
DELIMITER ;
-- 注1:如果有多个参数有,分开
-- 注2:COUNT(*) 函数返回表中的记录数
-- 注3:SELECT COUNT(*) INTO s FROM user;把user的值赋值给s

存储过程参数(in)

'存储过程参数'
存储过程 “in” 参数:跟 C 语言的函数参数的值传递类似, 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible)。
例子:

1
2
3
4
5
6
7
DELIMITER $$
CREATE PROCEDURE demo_in_parameter(IN p_in INT)
BEGIN
SET p_in = 2;-- 赋值
SELECT p_in;-- 接收p_in的值
END; $$
DELIMITER ;

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SET @p_in = 1;
CALL demo_in_parameter(@p_in);
+------+
| p_in |
+------+
| 1 |
+------+
+------+
| p_in |
+------+
| 2 |
+------+
SELECT @p_in;
+------+
| p_in |
+------+
| 1 |
+------+

总结:以上可以看出,p_in虽然在存储过程中改变了值 但是并不影响外部@p_in的值(值传递)

存储过程参数(out)

存储过程 “out” 参数:从存储过程内部传值给调用者。在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值
例子:

1
2
3
4
5
6
7
8
DELIMITER $$
CREATE PROCEDURE demo_out_paremter(OUT p_out INT)
BEGIN
SELECT p_out; -- 定义变量 后面没有给他赋值 默认为NULL
SET p_out = 2;
SELECT p_out;
END; $$
DELIMITER;

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SET @p_out = 1;
CALL demo_out_paremter(@p_out);
+------+
| p_out|
+------+
| NULL|
+------+
+------+
| p_out|
+------+
| 2 |
+------+
SELECT @p_out;
+------+
| p_out|
+------+
| 1 |
+------+

总结:由以上可以看出第一个值是为NULL 因为使用OUT参数时他会忽略掉所有的实际参数值 他会在存储过程内部进行赋值 然后存储过程结束后他会把值返回出去

存储过程参数(inout)

存储过程 inout 参数跟 out 类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过 inout 参数传递值给存储过程。
例子:

1
2
3
4
5
6
7
8
DELIMITER $$
CREATE PROCEDURE demo_inout_paremter(INOUT p_inout INT)
BEGIN
SELECT p_inout; -- 定义变量 后面没有给他赋值 默认为NULL
SET p_inout = 2;
SELECT p_inout;
END; $$
DELIMITER;

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SET @p_inout = 1;
CALL demo_inout_paremter(@p_inout);
+-------+
|p_inout|
+-------+
| 1 |
+-------+
+-------+
|p_inout|
+-------+
| 2 |
+-------+
SELECT @p_inout;
+-------+
|p_inout|
+-------+
| 2 |
+-------+

总结:存储过程 inout 参数的行为跟 C 语言函数中的引用传值类似

通过以上例子:如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。

删除存储过程

1
2
3
4
5
6
7
/*
DROP PROCEDURE tablename;(这里表后面没括号)如果指定的过程不存在,则将产生一个错误。当过程存在想删除它时(如果过程不存在也不产生错误)可使用
DROP PROCEDURE IF EXISTS (tablename)。
*/
-- 如果proc_first存在就删
DROP PROCEDURE IF EXISTS proc_first;
-- 注:IF EXISTS(相当于if())

存储过程调用

1
CALL 存储过程名字() 后面的括号必不可少

修改存储过程

1
2
3
4
ALTER PROCEDURE 存储过程名
BEGIN
SQL语句代码块
END

查看一个已存在的存储过程

1
SHOW CREATE PROCEDURE 存储过程名

列出所有的存储过程

1
SHOW  PROCEDURE STATUS

设置安全验证方式

1
2
3
SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。
DEFINER:表示按定义者拥有的权限来执行(默认为当前用户)
INVOKER:表示用调用者的权限来执行。默认情况下,系统指定为DEFINER

例:

1
2
3
4
5
6
7
8
DELIMITER $$;
CREATE DEFINER=`username`@`localhost` PROCEDURE `test`()
SQL SECURITY INVOKER
BEGIN
sql代码块
END $$

DELIMITER ;

总结:任意用户X访问此VIEW时,能否成功取决于X是否有调用该VIEW的权限,以及DEFINER是否有VIEW中的SELECT的权限。只需要修改创建同名用户或者修改DEFINER即可。

1
alter DEFINER = 'xx'@'localhost' view xxxx as ...

复合语句

1
2
3
4
5
[begin_label:]
BEGIN
[statement_list]
END
[end_label]

例:

1
2
3
4
5
6
7
8
9
10
11
CREATE PROCEDURE doiterate(p1 INT)
BEGIN
label1: LOOP
SET p1 = p1 + 1;
IF p1 < 10 THEN
ITERATE label1; -- 继续迭代
END IF;

LEAVE label1; -- 终止循环
END LOOP label1;
END;

存储子程序可以使用BEGIN … END复合语句来包含多个语句。
statement_list 代表一个或多个语句的列表。statement_list之内每个语句都必须用分号(;)来结尾。
复合语句可以被标记(有特殊含义 上面的loop意思就是重复执行begin … end的代码块 LEAVE退出)。除非begin_label存在,否则end_label不能被给出,并且如果二者都存在,他们必须是同样的。
mysql官网语法

MySQL存储过程的控制语句

变量作用域

内部的变量在其作用域范围内享有更高的优先权,当执行到end。变量时,内部变量消失,此时已经在其作用域外,变量不再可见了,应为在存储过程外再也不能找到这个申明的变量,但是你可以通过out参数或者将其值指派给会话变量来保存其值。

1
2
3
4
5
6
7
8
9
10
11
12
DELIMITER $$
CREATE PROCEDURE proc3()
BEGIN
DECLARE x1 VARCHAR(5) DEFAULT 'outer';
BEGIN
DECLARE x2 VARCHAR(5) DEFAULT 'inner';
SELECT x1;
END;
SELECT x1;
SELECT x2; -- 读取不到
END;$$
DELIMITER;

条件语句

条件判断语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IF

DELIMITER $$
CREATE PROCEDURE proc2(IN parameter INT)
BEGIN
DECLARE var INT;
SET var = parameter+1;
IF var = 0 THEN
INSERT INTO t VALUES(17); -- 插入
END IF;
IF parameter=0 THEN
UPDATE t SET s1=s1+1; -- 更新
ELSE
UPDATE t SET s1=s1+2;
END IF;
END;$$
DELIMITER ;
  • IF NOT EXISTS 即如果不存在 IF EXISTS 即如果存在

分支语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CASE

DELIMITER $$
CREATE PROCEDURE proc3 (IN parameter INT)
BEGIN
DECLARE var INT;
SET var = parameter + 1;
CASE
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;
---
CASE
WHEN var=0 THEN
INSERT INTO t VALUES(30);
WHEN var>0 THEN
WHEN var<0 THEN
ELSE
END CASE

循环1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WHILE ···· END WHILE

DELIMITER $$
CREATE PROCEDURE proc4()
BEGIN
DECLARE var INT;
SET var = 0;
WHILE var < 6 DO
INSERT INTO t VALUES(var);
SET var = var + 1;
END WHILE;
END;$$
DELIMITER ;
---
WHILE 条件 DO
--循环体
END WHILE

循环2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
REPEAT···· END REPEAT
它在执行操作后检查结果,而while则是执行前进行检查

DELIMITER $$
CREATE PROCEDURE proc5 ()
begin
DECLARE v INT;
SET v = 0;
REPEAT
INSERT INTO t VALUES(v);
SET v = v + 1;
UNTIL v > = 5
END REPEAT;
END; $$
DELIMITER ;
---
REPEAT
--循环体
UNTIL 循环条件
END REPEAT;

MySQL中的while循环和repeat循环的区别

  • while是满足条件才执行循环,repeat是满足条件退出循环;
  • while在首次循环执行之前就判断条件,最少执行0次,repeat是在首次执行循环之后才判断条件,循环至少执行一次。

循环3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LOOP ·····END LOOP
loop循环不需要初始条件,这点和while 循环相似,LEAVE语句的意义是离开循环。

DELIMITER $$
CREATE PROCEDURE proc6 ()
BEGIN
DECLARE v INT;
SET v=0;
LOOP_LABLE:LOOP -- 标签开始
NSERT INTO t VALUES(v);
SET v = v + 1;
IF v >= 5 THEN
LEAVE LOOP_LABLE; -- 退出循环
END IF;
END LOOP; -- 标签结束
END;$$
DELIMITER ;

标号

LABLES
标号可以用在BEGIN REPEAT WHILE 或者LOOP 语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。

迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ITERATE

DELIMITER $$
CREATE PROCEDURE proc10 ()
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 ;

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DELIMITER $$
DROP PROCEDURE IF EXISTS LOOPLoopProc$$
CREATE PROCEDURE LOOPLoopProc()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
loop_label: LOOP
IF x > 10 THEN
LEAVE loop_label;
END IF;
SET x = x + 1;
IF (x mod 2) THEN
ITERATE loop_label;
ELSE
SET str = CONCAT(str,x,',');
END IF;

END LOOP;
SELECT str;
END $$
DELIMITER ;

在上面存储过程中我们首先在LOOP语句开始前声明了一个loop_label,然后在if语句总判断变量x是否大于10,如果大于10会使用LEAVE语句退出循环,而如果x是奇数时则会回到循环开始继续执行,这有点像continue语句,否则对str执行concat操作,并进入下一次循环

总结:LOOP、LEAVE、ITERATE更像其他编程语言中的goto语句。 LOOP要设定一个label指定循环的开始位置,而LEAVE则像其他语言中的break会离开LOOP指定的块,ITERATE则会再次回到LOOP开始的语句

MySQL存储过程的基本函数

字符串类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    CHARSET(str) -- 返回字串字符集
CONCAT (string2 [,... ]) -- 连接字串
INSTR (string ,substring ) -- 返回substring首次在string中出现的位置,不存在返回0
LCASE (string2 ) -- 转换成小写
LEFT (string2 ,length ) -- 从string2中的左边起取length个字符
LENGTH (string ) -- string长度
LOAD_FILE (file_name ) -- 从文件读取内容
LOCATE (substring , string [,start_position ] ) -- 同INSTR,但可指定开始位置
LPAD (string2 ,length ,pad ) -- 重复用pad加在string开头,直到字串长度为length
LTRIM (string2 ) -- 去除前端空格
REPEAT (string2 ,count ) -- 重复count次
REPLACE (str ,search_str ,replace_str ) -- 在str中用replace_str替换search_str
RPAD (string2 ,length ,pad) -- 在str后用pad补充,直到长度为length
RTRIM (string2 ) -- 去除后端空格
STRCMP (string1 ,string2 ) -- 逐字符比较两字串大小,
SUBSTRING (str , position [,length ]) -- 从str的position开始,取length个字符,
注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1

select substring('abcd',0,2);
+-----------------------+
| substring('abcd',0,2) |
+-----------------------+
| |
+-----------------------+
1 row in set (0.00 sec)

select substring('abcd',1,2);
+-----------------------+
| substring('abcd',1,2) |
+-----------------------+
| ab |
+-----------------------+
1 row in set (0.02 sec)

TRIM([[BOTH|LEADING|TRAILING][padding] FROM]string2) -- 去除指定位置的指定字符
UCASE (string2 ) -- 转换成大写
RIGHT(string2,length) -- 取string2最后length个字符
SPACE(count) -- 生成count个空格

数学类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    ABS (number2 ) -- 绝对值
BIN (decimal_number ) -- 十进制转二进制
CEILING (number2 ) -- 向上取整
CONV(number2,from_base,to_base) -- 进制转换
FLOOR (number2 ) -- 向下取整
FORMAT (number,decimal_places ) -- 保留小数位数
HEX (DecimalNumber ) -- 转十六进制
注:HEX()中可传入字符串,则返回其ASC-11码,如HEX('DEF')返回4142143
也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19
LEAST (number , number2 [,..]) -- 求最小值
MOD (numerator ,denominator ) -- 求余
POWER (number ,power ) -- 求指数
RAND([seed]) -- 随机数
ROUND (number [,decimals ]) -- 四舍五入,decimals为小数位数]
注:返回类型并非均为整数,如:

(1)默认变为整形值
select round(1.23);
+-------------+
| round(1.23) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)

select round(1.56);
+-------------+
| round(1.56) |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)

(2)可以设定小数位数,返回浮点型数据
select round(1.567,2);
+----------------+
| round(1.567,2)
+----------------+
| 1.57 |
+----------------+
1 row in set (0.00 sec)

SIGN (number2 ) -- 返回参数作为-1、0或1的符号,该符号取决于number2的值为负、零或正

日期时间类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ADDTIME (date2 ,time_interval )-- 将time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) -- 转换时区
CURRENT_DATE ( ) -- 当前日期
CURRENT_TIME ( ) -- 当前时间
CURRENT_TIMESTAMP ( ) -- 当前时间戳
DATE (datetime ) -- 返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) -- 在date2中加上日期或时间
DATE_FORMAT (datetime ,FormatCodes ) -- 使用formatcodes格式显示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) -- 在date2上减去一个时间
DATEDIFF (date1 ,date2 ) -- 两个日期差
DAY (date ) -- 返回日期的天
DAYNAME (date ) -- 英文星期
DAYOFWEEK (date ) -- 星期(1-7) ,1为星期天
DAYOFYEAR (date ) -- 一年中的第几天
EXTRACT (interval_name FROM date ) -- 从date中提取日期的指定部分
MAKEDATE (year ,day ) -- 给出年及年中的第几天,生成日期串
MAKETIME (hour ,minute ,second ) -- 生成时间串
MONTHNAME (date ) -- 英文月份名
NOW ( ) -- 当前时间
SEC_TO_TIME (seconds ) -- 秒数转成时间
STR_TO_DATE (string ,format ) -- 字串转成时间,以format格式显示
TIMEDIFF (datetime1 ,datetime2 ) -- 两个时间差
TIME_TO_SEC (time ) -- 时间转秒数]
WEEK (date_time [,start_of_week ]) -- 第几周
YEAR (datetime ) -- 年份
DAYOFMONTH(datetime) -- 月的第几天
HOUR(datetime) -- 小时
LAST_DAY(date) -- date的月的最后日期
MICROSECOND(datetime) -- 微秒
MONTH(datetime) -- 月
MINUTE(datetime) -- 分返回符号,正负或0
SQRT(number2) -- 开平方

MySql分页存储过程

MySql测试版本:5.0.41-community-nt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
DROP PROCEDURE IF EXISTS pr_pager; -- 如果有这个存储过程就删除
CREATE PROCEDURE pr_pager(

IN p_table_name VARCHAR(1024),
IN p_fields VARCHAR(1024),
IN p_page_size INT,
IN p_page_now INT,
IN p_order_string VARCHAR(128),
IN p_where_string VARCHAR(1024),
OUT p_out_rows INT
)
NOT DETERMINISTIC -- 确定性
SQL SECURITY DEFINER -- 安全性
COMMENT '分页存储过程'

BEGIN
DECLARE m_begin_row INT DEFAULT 0;
DECLARE m_limit_string CHAR(64);

SET m_begin_row = (p_page_now - 1) * p_page_size;
SET m_limit_string = CONCAT(' LIMIT ', m_begin_row, ', ', p_page_size);

SET @COUNT_STRING = CONCAT('SELECT COUNT(*) INTO @ROWS_TOTAL FROM ', p_table_name, ' ', p_where_string);
SET @MAIN_STRING = CONCAT('SELECT ', p_fields, ' FROM ', p_table_name, ' ', p_where_string, ' ', p_order_string,m_limit_string);


PREPARE count_stmt FROM @COUNT_STRING;
EXECUTE count_stmt;
DEALLOCATE PREPARE count_stmt;
SET p_out_rows = @ROWS_TOTAL;

PREPARE main_stmt FROM @MAIN_STRING;
EXECUTE main_stmt;
DEALLOCATE PREPARE main_stmt;
END;

DETERMINISTIC

它表示一个函数在输入不变的情况下输出是否确定。如果你的函数当输入一样时,会返回同样的结果.这样, 数据库就用前一个计算的值,而不需要再重新计算一次.这对于使用函数索引等,会直到相当大的好处
调用:

1
2
call pr_pager("t","var",3,3,"","",@result);
call pr_pager("t","var",3,2,"","",@result);

select * into 用法

1
2
3
4
5
6
例1:
select id into result from table where id = 1
查找table表中id=1id赋值给result
1
select sum(id) into result from table where id = 1
查找tableid1的 把id全部加起来 再把值赋值给result

GROUP BY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
例1:
DELIMITER $$

DROP PROCEDURE IF EXISTS `p_get_integral`$$

CREATE PROCEDURE `p_get_integral`()
SQL SECURITY INVOKER
_RETURN:BEGIN
select roleid,concat(sum(itemnum),'') from log_delitem where itemid in(920,2983) and info ='道具' and usetime >= '2019-01-30 00:00:00' and usetime <= '2019-01-30 10:40:00' group by roleid;
END;$$

DELIMITER ;

查找log_delitem表中itemid = 920,2983 info信息等于'道具' 时间在'2019-01-30 00:00:00'和'2019-01-30 10:40:00'之间数据按roleid分组 再查找满足条件的roleid和itemnum值的总和

查看列数

1
2
3
4
select count(*)
from information_schema.COLUMNS
where TABLE_SCHEMA='ddd' and table_name='ttt'
ps:'ddd'='库名' 'ttt'='表名'

查看行

1
2
select count(*) from 'ttt'
ps:'ttt'='表名'

-------------本文结束感谢您的阅读-------------