对select into
语句感兴趣是因为看了项目中的一个存储过程引起的,在程序运行之前看了存储过程的逻辑,本以为没有数据时会报错,结果程序却正常运行,这说明我对select into
语句理解的问题,同时也暴露了一个知识盲点,所以写了个小例子测试一下,并把测试的过程记录方便日后查找。
为了更清楚的表明问题,我们创建的表格尽可能的简单,同时为了测试空值的情况,数据列我们不设置默认值,表格命名为’intotest’,创建语句如下:
CREATE TABLE `intotest` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`number` int(4),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=binary ROW_FORMAT=DYNAMIC;
表格建立完成可以使用可视化工具或者insert语句插入测试数据,插入测试数据后查询结果如下:
mysql> select * from intotest;
+----+--------+
| id | number |
+----+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | NULL |
+----+--------+
3 rows in set (0.00 sec)
我们建立一个用于测试的存储过程,主要的逻辑就是看看当select into
语句找不到匹配记录时,被赋值的变量会怎么样,建立存储过程的代码如下:
CREATE PROCEDURE `select_into_value2`()
BEGIN
DECLARE _value INT DEFAULT 0;
SELECT number FROM intotest WHERE id=1 INTO _value;
SELECT _value;
END
这个存储过程运行正常,配合刚才我们插入表格的记录可以知道,运行后的结果为1:
mysql> call select_into_value();
+--------+
| _value |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
CREATE PROCEDURE `select_into_value2`()
BEGIN
DECLARE _value INT DEFAULT 0;
SELECT number FROM intotest WHERE id=5 INTO _value;
SELECT _value;
END
mysql> call select_into_value();
+--------+
| _value |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
结果为0,也就是说当查不到匹配结果时,不会执行select into
的赋值效果。
CREATE PROCEDURE `select_into_value2`()
BEGIN
DECLARE _value INT DEFAULT 0;
SELECT number FROM intotest WHERE id=3 INTO _value;
SELECT _value;
END
mysql> call select_into_value();
+--------+
| _value |
+--------+
| NULL |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
结果为NULL,也就是说当查到匹配结果时,不管结果时什么都会赋值到指定的变量中(类型不匹配的sql错误除外)。
CREATE PROCEDURE `select_into_value2`()
BEGIN
DECLARE _value INT DEFAULT 0;
SELECT number FROM intotest WHERE id=2 INTO _value;
SELECT number FROM intotest WHERE id=5 INTO _value;
SELECT _value;
END
mysql> call select_into_value();
+--------+
| _value |
+--------+
| 2 |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
想必明白了前两种情况,这第三种也应该明白了,两条语句顺序执行,找到匹配的就赋值,找不到就放弃操作,结果就保留了上一次成功赋值的结果。
select into
语句赋值的规则就一句话,找到了符合条件的记录就赋值,找不到就算了。