之前写过一篇MySQL Tips,虽与本篇没有什么连续性,但都是MySQL相关的整理,不妨一看。
大体上定义变量的形式分为两种,后两者表现基本一致,差别细微:DECLARE、SET/SELECT
使用DECLARE一次可以定义多个同类型的变量,各变量名称之间以逗号“,”隔开,
但是不能像SQLServer一样同时定义多个不同类型的变量如:DECLARE a INT,b CHAR(1)
定义规则如下:DECLARE 变量名[,...] 类型 DEFAULT [默认值]
注意:同时定义的多个变量只能有一个默认值,如:DECLARE a,b,c INT DEFAULT 0;
两者的基本区别分别是:(引用自:mysql的set和declare区别)
此外,实际使用中还有以下需要注意的点:
参考:用户变量
USE test; DROP PROCEDURE IF EXISTS pro_test; DELIMITER $$ CREATE PROCEDURE pro_test(a INT,IN b INT,OUT c INT,OUT d INT,OUT e INT,INOUT f INT) BEGIN DECLARE x,y INT DEFAULT 5; SELECT a,@a,b,@b,c,@c,d,@d,e,@e,f,@f,@z,x,@x,y,@y; SET a=10,@a=100,b=20,@b=200,c=30,@d=400,f=60,x=70; SELECT @y:=70,@f:=600; #SET z=90; SET @z=900; #SELECT z; SELECT a,@a,b,@b,c,@c,d,@d,e,@e,f,@f,@z,x,@x,y,@y; END$$ DELIMITER ; SET @b:=2,@c=3,@f=6; SELECT @d=4,@e:=5; CALL pro_test(1,@b,@c,@d,@e,@f); SELECT @a,@b,@c,@d,@e,@f;以上SQL执行结果如下图所示:
结果有点混乱,做几点说明:
CREATE PROCEDURE test.test() BEGIN loop_label: LOOP IF TRUE THEN LEAVE loop_label; END IF; PREPARE s1 FROM 'SELECT 1'; EXECUTE s1; END LOOP; DEALLOCATE PREPARE s1; END$$
CREATE PROCEDURE test.test() BEGIN PREPARE s1 FROM 'SELECT 1'; loop_label: LOOP IF TRUE THEN LEAVE loop_label; END IF; EXECUTE s1; END LOOP; DEALLOCATE PREPARE s1; END$$
以下内容分别引用自:mysql游标循环的使用、MySQL存储过程变量用Declare,Declare要注意的几点:
注意,声明各种变量的顺序。首先要进行变量声明,然后声明条件,随后声明游标,再后面才是声明错误处理器,如果没有按照顺序声明,系统会提示错误信息。
DECLARE语句必须用在DEGIN…END语句块中,并且必须出现在DEGIN…END语句块的最前面,即出现在其他语句之前
DECLARE定义的变量的作用范围仅限于DECLARE语句所在的DEGIN…END块内及嵌套在该块内的其他DEGIN…END块
存储过程中的变量名不区分大小写.
CREATE PROCEDURE test.pro_test() BEGIN DECLARE i INT DEFAULT 0; PREPARE s1 FROM 'SELECT ?'; loop_label: LOOP IF i > 1000000 THEN LEAVE loop_label; END IF; SET i=i+1; EXECUTE s1 USING @i; END LOOP; DEALLOCATE PREPARE s1; END$$ CREATE PROCEDURE test.pro_test2() BEGIN DECLARE i INT DEFAULT 0; loop_label: LOOP IF i > 1000000 THEN LEAVE loop_label; END IF; SET i=i+1; PREPARE s1 FROM 'SELECT ?'; EXECUTE s1 USING @i; DEALLOCATE PREPARE s1; END LOOP; END$$ CREATE PROCEDURE test.pro_test3() BEGIN DECLARE i INT DEFAULT 0; loop_label: LOOP IF i > 1000000 THEN LEAVE loop_label; END IF; SET i=i+1; SELECT i; END LOOP; END$$
分别对比以上三个存储过程的执行时间:
time mysql -uroot -ptest -Ne 'CALL test.pro_test()'>/dev/null # real 0m17.314s # user 0m7.055s # sys 0m1.305s time mysql -uroot -ptest -Ne 'CALL test.pro_test2()'>/dev/null # real 0m36.291s # user 0m7.568s # sys 0m1.419s time mysql -uroot -ptest -Ne 'CALL test.pro_test3()'>/dev/null # real 0m17.293s # user 0m7.650s # sys 0m0.795s
需要申明的是以上测试的SQL语句比较简单,并不能代表真实情况。
显然,MySQL 动态语句的构建和清理需要耗费大量的时间和空间,
此外,预处理和硬编码的SQL执行差异不大,关键在于具体执行语句的分析和检索过程。
参考:MySQL中Stmt 预处理提高效率问题的小研究
以下存储过程包含上文所述的变量、游标、循环、预处理等相关语句的使用:
CREATE PROCEDURE test.new_procedure(db VARCHAR(100)) BEGIN DECLARE tb,col VARCHAR(100); DECLARE done TINYINT DEFAULT FALSE; DECLARE cur CURSOR FOR SELECT TABLE_NAME,COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=IF(DATABASE()=db,'test',db); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; PREPARE s1 FROM 'SELECT ?,?'; OPEN cur; read_loop: LOOP FETCH cur INTO tb,col; IF done THEN LEAVE read_loop; END IF; EXECUTE s1 USING @tb,@col; END LOOP; CLOSE cur; DEALLOCATE PREPARE s1; END$$
需要注意的是 DATABASE()函数的使用,无论在哪个库调用该过程,返回的结果都是test,
所以要传递库名的话需要给存储过程增加参数。
很久以前就看不惯黑压压的linux终端窗口了,那就来一番装修八:
# man美化 mkdir ~/.terminfo && cd ~/.terminfo wget -q http://nion.modprobe.de/mostlike.txt tic mostlike.txt echo 'alias man="TERMINFO=~/.terminfo/ LESS=C TERM=mostlike PAGER=less man"' >> ~/.bash_profile # 终端美化 wget -q http://cwrapper.sourceforge.net/cw-1.0.16.tar.gz tar xf cw-1.0.16.tar.gz cd cw-1.0.16 ./configure && make install echo 'export PATH=/usr/local/lib/cw:$PATH' >> ~/.bash_profile
以上内容整理自:让bash的man看上去多姿多彩;
此外,mysql终端查询的数据量一多就眼花缭乱,还好在SF上已有高人做出解答,那就是神奇的colour-mysql-console。
它是利用pager(MySQL内部用于过滤或者格式化结果集的自带命令)调用外部的格式化程序将结果集输出为带颜色变量的字符,
它这里使用的是python程序grc做的处理,安装过程如下:
wget http://korpus.juls.savba.sk/~garabik/software/grc/grc_1.9.orig.tar.gz tar xf grc_1.9.orig.tar.gz cd grc-1.9 sh install.sh
wget https://github.com/nitso/colour-mysql-console/archive/master.zip -O master.zip unzip -q master.zip mv colour-mysql-console-master/* ~参考: Mysql Color Scheme,值得一提的是作者说他花了一年才搞定这个事情!