我想给MySQL用户创build新数据库的能力,并且对这些数据库拥有所有的权限,但不能在其他数据库上。 我试图为此创build一个存储过程,但它不工作。 这是我的程序( 注意:下面的更新代码):
DELIMITER // CREATE DEFINER = 'root'@'localhost' PROCEDURE createdb(IN newdb VARCHAR(255)) BEGIN CREATE DATABASE newdb; SET @newdbuser = USER(); GRANT ALL ON newdb.* TO '@newdbuser'; FLUSH PRIVILEGES; END // DELIMITER ;
我打电话给程序使用:
CALL createdb('newtestdb');
但是会发生的是数据库'newdb'(variables名称)被创build。 尝试访问该数据库作为调用该过程的凡人用户不能正常工作:访问被拒绝。
问题:我的程序有什么问题 ? 还是我从错误的angular度来攻击这个问题呢?
更新基于longneck的答案,我已经修改过程为:
DELIMITER // CREATE DEFINER = 'root'@'localhost' PROCEDURE createdb(IN newdb VARCHAR(255)) BEGIN PREPARE stmt1 FROM "CREATE DATABASE ?"; PREPARE stmt2 FROM "GRANT ALL ON newdb.* TO '?'"; EXECUTE stmt1 USING @newdb; SET @newdbuser = USER(); EXECUTE stmt2 USING @newdbuser; FLUSH PRIVILEGES; END // DELIMITER ;
但是,使用“CALL createdb('testing')”调用此过程时, 我得到:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
我错过了什么?
这不是一个权利问题。 mysql不支持variables作为对象名称(对象是表,数据库,列等)。 您将不得不使用准备好的语句并以stringforms构build您的命令。 请参阅http://forums.mysql.com/read.php?98,152150,152161#msg-152161
例如,您的PREPARE语句需要如下所示:
PREPARE stmt1 FROM concat("CREATE DATABASE ", @dbname); PREPARE stmt2 FROM concat("GRANT ALL ON newdb.* TO ", @username);
不是说这不是注射安全的。 确保在使用这些语句之前已经清理了“参数”(数据库名称,用户名)。
另外,您授予您的权限错误。 TO '@newdbuser'将权限分配给从一台名为newdbuser的计算机连接的用户。 您需要在用户名后面加上@符号。
没有像CREATE DATABASE这样的特权。 只有CREATE权限授予数据库,表和索引的创build