从MySQL 5.5.3开始,如果不选择数据库,则无法使用别名引用删除?

nob*_*ody 6 mysql

我以前做过这样复杂的多表DELETE:

DELETE db1.t1 FROM db1.table1 AS t1, db1.table2 AS t2...
Run Code Online (Sandbox Code Playgroud)

现在升级到MySQL 5.5.5之后不再起作用,因为根据文档,因为5.5.3别名不允许在DELETE语句中使用db name进行限定.所以我应该这样做:

DELETE t1 FROM db1.table1 AS t1, db1.table2 AS t2...
Run Code Online (Sandbox Code Playgroud)

由于错误#61376并且给出错误1046(3D000)而无法正常工作:未选择数据库.

我不使用数据库,因为我的代码应该可以在未知环境中集成,并且选择db可能会破坏现有代码.

我是否应该假设在没有选择数据库的情况下不能选择数据库的DELETE语句,因为MySQL 5.5.3和我应该开始寻找一个肮脏的黑客,或者你知道一个干净的解决方案吗?


更新:

USE db1没有选择数据库时添加此查询之前(Bill Karwin的建议):

DELETE t1 FROM db1.table1 AS t1, db1.table2 AS t2...
Run Code Online (Sandbox Code Playgroud)

使它在5.5.5中工作,但在4.1和5.1中它都给出了这个错误:

ERROR 1109 (42S02): Unknown table 't1' in MULTI DELETE
Run Code Online (Sandbox Code Playgroud)

我想现在我将完全放弃使用别名,而是在任何地方使用完整的db.table名称,这使得查询变得大而且不可读但我想不出任何更好的解决方案.

Bil*_*win 5

我只准备一个默认数据库.不幸的USE db1是,与访问表的任何实际查询相比,它是必要的,但实际上并不是重要的运行语句.

您不必为每个DELETE执行两个查询.将SELECT DATABASE()在bug报告中显示是没有必要的,它只是表明没有默认数据库被选中.

您只需要为每个会话准备一次默认数据库,例如,在您连接之后,而不是在每个语句之前.


你的评论:

如果你正在使用另一个数据库,那么错误就会消失.只有当您没有数据库作为默认值时,才会出现别名错误.您不一定要准备db1从中删除.

我现在没有时间测试所有排列,所以部分原因是基于假设.


重新更新:

多年来,MySQL已经改变了几次行为.我建议你建议升级5.1之前的任何MySQL,并确保你使用的是InnoDB插件.它不仅可以简化您的开发,还可以获得近年来的可扩展性改进.

MySQL 4.1/5.0/5.1说:

从MySQL 4.1.2开始,可以使用别名,但是对于要从中删除行的表列表中的别名引用,除非明确指定了一个数据库,否则将使用默认数据库.

要正确匹配引用默认数据库之外的表的别名,必须使用正确数据库的名称显式限定引用:

DELETE a1, db2.a2 FROM db1.t1 AS a1 INNER JOIN db2.t2 AS a2
WHERE a1.id=a2.id;
Run Code Online (Sandbox Code Playgroud)

MySQL 5.5说:

从MySQL 5.5.3开始,别名解析不需要限定,别名引用不应该使用数据库名称限定.限定名称被解释为引用表而不是别名.

所以你是对的,你不能在跨越多个数据库的多表删除中使用别名,并且对于4.1/5.0/5.1而不是5.5具有相同的代码.解决方法是跳过别名并提供由数据库限定的表的全名.

这应该有效,除非您有一个涉及自连接和跨数据库连接的多表DELETE.