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
	
相关新闻>>
- 发表评论
 - 
				
 
- 最新评论 进入详细评论页>>
 





