Mysql的Procedure 参数为NULL问题分析
最近写过程时发现一个有趣的事情,Mysql 的procedure 在传参的过程中,遇到一些“非法”的参数是有自己独特的处理方式。例如本来定义是int的参数,结果被传入的是null
,mysql 的procedure会正常执行。
库表结构:
create database db5;
use db5;
drop table if exists t;
create table t(
id int primary key auto_increment,
value int
);
create table t2(
id int primary key auto_increment,
value float
);
创建procedure:
delimiter //
CREATE PROCEDURE p14 (IN parameter1 INT)
BEGIN
DECLARE variable1 INT;
SET variable1 = parameter1 + 1;
INSERT INTO t(value) VALUES (variable1);
END;
//
delimiter ;
运行结果:
mysql> call p14(5);
Query OK, 1 row affected (0.02 sec)
mysql> select * from t;
+----+-------+
| id | value |
+----+-------+
| 2 | 6 |
+----+-------+
1 row in set (0.00 sec)
mysql> call p14(null);
Query OK, 1 row affected (0.04 sec)
mysql> select * from t;
+----+-------+
| id | value |
+----+-------+
| 2 | 6 |
| 3 | NULL |
+----+-------+
2 rows in set (0.00 sec)
大家注意到没有,当参数parameter1传入等于5时,表插入6,数据正常。
当参数parameter1传入为null时,表插入NULL,这是为什么呢。
关于这点大家可以看看声明变量的语句,文档给出了这样的解释:declare这个语句被用来声明局部变量。要给变量提供一个默认值,请包含一个DEFAULT子句。值可以被指定为一个表达式,不需要为一个常数。如果没有DEFAULT子句,初始值为NULL。
上面这样又有了一个新的问题:NULL=NULL+1?哈哈,有点意思了,此时的SET variable1 = parameter1 + 1;会有一个怎样合理的解释呢?
这是王老师给的解释(第二条很经典呀~~~):
1 null+1=null
因为null表现为“类似指针”,也就是指向“0地址的内容”,如果这个内容为“null”,则表现为null。这就是指定INT也为空的原因。但是,如果“内容”有值,则表现为不空,对于MYSQL而言,是个“随机数”或0;当这个地址内容存储时,值就固定了;
2 如果A=B+1,只有B为null时,A才为NULL;SET A=B+1,是否可理解为SET (B+1),A已经在‘当前’替换,这样A是谁不重要,重要的是B+1;
本想法没有验证,主要是分离不了SET,而mysql5的文档,有支持这一说法,但英文版本是用“替换”,不是中文的“设置”表达,感觉意思更为接近!(SET)
一个新的问题:当A=1/B,B=0时,也能运行成功吗?
mysql>
delimiter //
CREATE PROCEDURE p15 (IN parameter1 INT)
BEGIN
declare variable2 float(5,3);
SET variable2 =1/ parameter1;
INSERT INTO t2(value) VALUES (variable2);
END;
//
delimiter ;
执行结果:
mysql> call p15(0);
Query OK, 1 row affected (0.03 sec)
mysql> select * from t2;
+----+-------+
| id | value |
+----+-------+
| 1 | NULL |
+----+-------+
1 row in set (0.00 sec)
mysql> call p15(1);
Query OK, 1 row affected (0.03 sec)
mysql> select * from t2;
+----+-------+
| id | value |
+----+-------+
| 1 | NULL |
| 2 | 1 |
读者注意没有? 这个也能运行成功。其实这个问题在mysql的SQL服务器模式参数细节中可以找到。
MySQL服务器可以以不同的SQL模式来操作,并且可以为不同客户端应用不同模式。这样每个应用程序可以根据自己的需求来定制服务器的操作模式。
模式定义MySQL应支持哪些SQL语法,以及应执行哪种数据验证检查。这样可以更容易地在不同的环境中使用MySQL,并结合其它数据库服务器使用MySQL。
你可以用--sql-mod
相关新闻>>
- 发表评论
-
- 最新评论 更多>>