是的,但现在它更"喜欢"它们,原因如下。
介绍
使用 LIKE 子句过滤特定表中的触发器或视图很常见。但是,它可能会欺骗您,特别是如果您看不到输出(即在非交互式会话中)。让我们看一个简单的例子,以及如何以更可靠的方式处理任务。还有一个指向 mydumper 错误的额外链接,该错误是根据本实验室的调查而修复的。是的,但现在它更喜欢它们,原因如下。
实验室
首先,我们将创建两个只有一个无符号整数列的虚拟表。该列也将是两个表的主键。
sql
CREATE TABLE `test_lab` (
`id` int unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `test2lab` (
`id` int unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
我们还将创建第三个表,它将作为我们的"日志"来跟踪前两个表中所做的插入。我们将在这里使用复合主键(表名称和 ID)。
sql
CREATE TABLE `log_lab` (
`changed_table` varchar(50) NOT NULL,
`id` int unsigned NOT NULL,
PRIMARY KEY (`changed_table`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
现在,让我们为每个表添加一个触发器。两个表的触发器相同,并将记录复制到日志表。
sql
DELIMITER //
CREATE TRIGGER `test_lab_trigger_INS` AFTER INSERT ON `test_lab`
FOR EACH ROW BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END
//
CREATE TRIGGER `test2lab_trigger_INS` AFTER INSERT ON `test2lab`
FOR EACH ROW BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END
//
DELIMITER ;
最后,让我们检查一下我们是否正确完成了所有操作:
sql
mysql> insert into `test_lab` values (8) ;
Query OK, 1 row affected (0.00 sec)
mysql> insert into `test2lab` values (2) ;
Query OK, 1 row affected (0.01 sec)
mysql> select * from log_lab ;
+---------------+----+
| changed_table | id |
+---------------+----+
| test_lab | 8 |
| test2lab | 2 |
+---------------+----+
2 rows in set (0.00 sec)
现在,我们已准备好运行我们为其创建实验室的测试用例。让我们从使用这个语句开始:
sql
mysql> SHOW TRIGGERS LIKE 'test2lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
一张表,一个触发器,一行。都可以。
这次,我们将使用其他表名称:
sql
mysql> SHOW TRIGGERS LIKE 'test_lab' ;
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
| test_lab_trigger_INS | INSERT | test_lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
2 rows in set (0.00 sec)
人们可能会惊讶地看到两个表都有两行及其触发器,但这是预期的行为。 LIKE 语句不会根据模式执行严格的比较和过滤。您仍然可以在其中使用通配符 (%),它可以用来代替搜索字符串中任意数量的字符。在 LIKE 语句中使用占位符 () 来匹配任何单个字符的情况不太常见。讽刺的是,我们使用占位符匹配表名称中的""和"2"字符。
在文章的开头,我承诺展示一种更可靠的方法来处理该任务,所以这里是:
sql
mysql> SHOW TRIGGERS WHERE `Table` = 'test2lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test2lab_trigger_INS | INSERT | test2lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test2lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)
mysql> SHOW TRIGGERS WHERE `Table` = 'test_lab';
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
| test_lab_trigger_INS | INSERT | test_lab | BEGIN
INSERT INTO log_lab (`changed_table`,`id`) VALUES ('test_lab', NEW.id) ;
END | AFTER | 2024-04-13 10:35:45.29 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | msandbox@localhost | utf8mb4 | utf8mb4_0900_ai_ci | utf8mb4_0900_ai_ci |
+----------------------+--------+----------+------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------------------------------------------------------------------------+--------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
您可以过滤输出中的任何其他列,不限于表。不要忘记使用 Table
,因为它是 MySQL 中的保留字,如果不使用它们(以及大多数其他列名),您将无法逃脱。
如果您想做自己的实验,我将留给读者使用 VIEW 进行相同的测试。
题外话
这时,你可能会问这个极端案例与现实世界有什么关系。当一个包含下划线而另一个包含数字时,表名称略有不同的情况并不常见。除了无法获得您愿意获得的输出之外,这也是 mydumper/myloader 中出现错误的原因,我在此报告:
Mydumper 将每个表的触发器放入单独的文件中,并使用 LIKE 语句导致属于 test2lab
的触发器最终出现在 test_lab
触发器文件中。
结论
本文介绍了了解运算符如何在 LIKE 子句示例中精确执行的重要性、如何创建快速实验室来测试命令的结果以确保结果,以及如何使用运算符替代 LIKE。
更多技术文章,请访问:opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。