过程参数名称TABLE_NAME 和表列名称table_name 之间存在歧义。应该避免它,因为它会导致像这样的模糊问题。
在这种情况下,在过程内部,反引号中的TABLE_NAME、table_name 和table_name 都是interpreted as the local variable name(参数名称)。因此,您的条件'where table_name = ',TABLE_NAME 始终为真;当您将TABLE_NAME 替换为"rooms" 文字时,如果您以"rooms" 作为参数调用该过程,则条件始终为真,否则始终为假。考虑这个简化的例子:
DROP PROCEDURE IF EXISTS pr;
DROP TABLE IF EXISTS t;
CREATE PROCEDURE pr (IN TABLE_NAME VARCHAR(255))
SELECT `id`, `table_name`, TABLE_NAME FROM t
;
CREATE TABLE t (id INT, `table_name` VARCHAR(255));
INSERT INTO t VALUES (1,'hotels'),(2,'rooms');
CALL pr("rooms");
CALL pr("foo");
你会得到
MariaDB [test]> CALL pr("rooms");
+------+--------------+------------+
| id | `table_name` | TABLE_NAME |
+------+--------------+------------+
| 1 | rooms | rooms |
| 2 | rooms | rooms |
+------+--------------+------------+
2 rows in set (0.00 sec)
MariaDB [test]> CALL pr("foo");
+------+--------------+------------+
| id | `table_name` | TABLE_NAME |
+------+--------------+------------+
| 1 | foo | foo |
| 2 | foo | foo |
+------+--------------+------------+
2 rows in set (0.00 sec)
如您所见,无论参数如何,对于所有行,table_name 始终等于 TABLE_NAME。
现在,如果您将 TABLE_NAME 替换为显式 "rooms":
DROP PROCEDURE IF EXISTS pr;
DROP TABLE IF EXISTS t;
CREATE PROCEDURE pr (IN TABLE_NAME VARCHAR(255))
SELECT `id`, `table_name`, "rooms" FROM t
;
CREATE TABLE t (id INT, `table_name` VARCHAR(255));
INSERT INTO t VALUES (1,'hotels'),(2,'rooms');
CALL pr("rooms");
CALL pr("foo");
现在条件table_name = "rooms"对于所有行的第一次调用为真,对于所有行的第二次调用为假:
MariaDB [test]> CALL pr("rooms");
+------+--------------+-------+
| id | `table_name` | rooms |
+------+--------------+-------+
| 1 | rooms | rooms |
| 2 | rooms | rooms |
+------+--------------+-------+
2 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> CALL pr("foo");
+------+--------------+-------+
| id | `table_name` | rooms |
+------+--------------+-------+
| 1 | foo | rooms |
| 2 | foo | rooms |
+------+--------------+-------+
2 rows in set (0.00 sec)
您需要的是一个不同的参数名称:
DROP PROCEDURE IF EXISTS pr;
DROP TABLE IF EXISTS t;
CREATE PROCEDURE pr (IN T_NAME VARCHAR(255))
SELECT `id`, `table_name`, T_NAME FROM t
;
CREATE TABLE t (id INT, `table_name` VARCHAR(255));
INSERT INTO t VALUES (1,'hotels'),(2,'rooms');
CALL pr("rooms");
CALL pr("foo");
现在比较table_name = T_NAME实际上是有道理的;
MariaDB [test]> CALL pr("rooms");
+------+------------+--------+
| id | table_name | T_NAME |
+------+------------+--------+
| 1 | hotels | rooms |
| 2 | rooms | rooms |
+------+------------+--------+
2 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> CALL pr("foo");
+------+------------+--------+
| id | table_name | T_NAME |
+------+------------+--------+
| 1 | hotels | foo |
| 2 | rooms | foo |
+------+------------+--------+
2 rows in set (0.00 sec)