Mysql 通过存储过程创建具有动态名称的表

Mysql 通过存储过程创建具有动态名称的表,mysql,stored-procedures,dynamic,Mysql,Stored Procedures,Dynamic,我正在尝试创建具有动态名称的表。我从中得到错误的代码是一段动态SQL。我不确定是什么问题。我不熟悉动态SQL和存储过程 PREPARE stmt FROM "CREATE TABLE `?` SELECT lat, lon, nfldtime FROM position_reports where mmsi = ? ORDER BY id DESC LIMIT 100"; EXECUTE stmt USING CONCAT("mmis", FORMAT(vesselID

我正在尝试创建具有动态名称的表。我从中得到错误的代码是一段动态SQL。我不确定是什么问题。我不熟悉动态SQL和存储过程

    PREPARE stmt FROM "CREATE TABLE `?` SELECT lat, lon, nfldtime FROM position_reports where mmsi = ? ORDER BY id DESC LIMIT 100";    

    EXECUTE stmt USING CONCAT("mmis", FORMAT(vesselID,0)), vesselID;
尝试创建过程时出现的错误是:

脚本行:4您的SQL语法有错误;检查手册 对应于MySQL服务器版本的正确语法 使用接近“CONCAT”(“mmis”,格式(vesselID,0)),vesselID

我试过这个:

编辑:

从@Konerak-answer开始,这项功能现在起作用了:

set @s = CONCAT("CREATE TABLE mmsi", vesselID, " SELECT lat, lon, nfldtime FROM position_reports where mmsi = ", vesselID, " ORDER BY id DESC LIMIT 100");
prepare createTable from @s;
EXECUTE createTable;
DEALLOCATE PREPARE createTable;

不能在准备好的语句中用
替换表名,然后让execute插入表名

动态表名通常是一个坏主意:最好创建一个大表,并为“虚拟表名”添加一个额外的(索引)列

如果确实需要动态表,则必须将表名压缩到PREPARE本身中

动态表名的正反两方面 假设不是将所有用户放在一个表中,
users
ID
Name
e-mail
country
.
,而是将它们放在动态表中,
users\u country
,列
ID
Name
e-mail

  • 您无法轻松查询所有表。假设你想知道你的用户中有多少是男性——你必须查询每个表,并合并结果。不会更快的

  • 您仍然可以使用分区来物理拆分表,但您的逻辑视图仍然是相同的。您认为使用单独的表具有的任何优势通常都可以通过另一种方法实现


我不希望有带有动态名称的表,但是我不得不这样做。也许您可以详细解释一下为什么这是一个糟糕的想法。噢,有时候,有多个表具有相同类型的数据,但它们是分开的,这是有好处的。但这种情况很少见,而且往往是出于错误的原因。让我来编辑这篇文章。你为什么被迫这么做?他们发明的理由是什么?为什么一个有额外索引列的表是不够的?如果需要限制某些用户的访问权限,则始终可以在表上创建视图。因为第三个软件需要指向实际的表。。不要问我为什么,因为我不知道。第三个软件可以指向一个视图吗?如果没有,就认输吧,问问他们——有时我们不得不接受“我们需要它来与另一个我们现在无法更改的应用程序兼容”——dynamic prepared语句应该可以工作。