groovy MySQLSyntaxErrorException和CREATE DATABASE(如果不存在)

groovy MySQLSyntaxErrorException和CREATE DATABASE(如果不存在),mysql,groovy,Mysql,Groovy,我不明白为什么或者怎么可能在这里出现语法错误。代码如下: def dbname = "liberalgeek_wp" def dbinfo = [url: 'jdbc:mysql://localhost:3306/mysql', user: dbuser, password: dbpass, driver: 'com.mysql.jdbc.Driver'] println("db info: ${dbinfo}\n\n") def db = Sql.newInstance(dbinfo.url

我不明白为什么或者怎么可能在这里出现语法错误。代码如下:

def dbname = "liberalgeek_wp"
def dbinfo = [url: 'jdbc:mysql://localhost:3306/mysql', user: dbuser, password: dbpass, driver: 'com.mysql.jdbc.Driver']
println("db info: ${dbinfo}\n\n")

def db = Sql.newInstance(dbinfo.url, dbinfo.user, dbinfo.password, dbinfo.driver)

def create_db_sql = "create database if not exists ${dbname}"
println("sql: ${create_db_sql}\n\n")
db.execute(create_db_sql)
以下是我运行它时的输出:

db info: [url:jdbc:mysql://localhost:3306/mysql, user:kenny, password:xxxxxx, driver:com.mysql.jdbc.Driver]

sql: create database if not exists liberalgeek_wp

Mar 18, 2017 4:03:59 PM groovy.sql.Sql execute
WARNING: Failed to execute: create database if not exists ? because: 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 ''liberalgeek_wp'' at line 1
Caught: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 ''liberalgeek_wp'' at line 1
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 ''liberalgeek_wp'' at line 1
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)
    at setup_wordpress.createMySQLDatabase(setup_wordpress.groovy:125)
我无法想象这个命令可能会有什么语法错误,所以我打开命令行并使用groovy脚本使用的相同用户/通行证登录到mysql。我将命令复制/粘贴到mysql中,效果很好:

Kenny-iMac:~$ mysql -ukenny -p mysql
Enter password: xxxxxx

mysql> create database if not exists liberalgeek_wp;
Query OK, 1 row affected, 1 warning (0.00 sec)

出了什么问题?

您的问题是试图使用
准备好的语句执行此语句。但是,在准备好的语句中不允许使用DDL指令(如create database),因为数据库名称不能绑定到变量

在这种特殊情况下,您可以做什么:直接构建查询,而不使用准备好的语句


我必须更准确地说:事实上,在准备好的语句中允许使用DDL语句,但不能将变量绑定到数据库、表或列名等名称。但是,您可以将变量绑定到其他对象,例如默认值,甚至可以设置参数值,尽管我没有对此进行测试。

您的问题是,您试图使用
准备好的语句执行此语句。但是,在准备好的语句中不允许使用DDL指令(如create database),因为数据库名称不能绑定到变量

在这种特殊情况下,您可以做什么:直接构建查询,而不使用准备好的语句


我必须更准确地说:事实上,在准备好的语句中允许使用DDL语句,但不能将变量绑定到数据库、表或列名等名称。但是,您可以将变量绑定到其他对象,例如默认值,甚至可能是设置参数值,尽管我没有对此进行测试。

在调用中使用executeUpdate而不是execute,并且不使用GString,在这之前解析字符串,认为这是为了防止SQL注入

....
def create_db_sql = 'create database if not exists ' + dbname
println("sql: ${create_db_sql}\n\n")

db.executeUpdate( create_db_sql )
....

使用MySQL版本5.7.17测试,使用executeUpdate而不是execute,并且在调用中不使用GString,在此之前解析字符串,认为这是为了防止SQL注入

....
def create_db_sql = 'create database if not exists ' + dbname
println("sql: ${create_db_sql}\n\n")

db.executeUpdate( create_db_sql )
....

使用MySQL 5.7.17版进行测试。这段代码运行得很好,谢谢你。当我的失败时,我试图弄明白为什么它能起作用,@Psi的答案给了我一个指示。事实证明,当使用GString时,Sql类解析GString以提取变量并从中构建一个准备好的语句,正如他所说的,改变DDL的查询不允许成为准备好的语句。这段代码运行得很好,谢谢你。当我的失败时,我试图弄明白为什么它能起作用,@Psi的答案给了我一个指示。事实证明,当使用GString时,Sql类解析GString以提取变量并从中构建一个准备好的语句,正如他所说的,改变DDL的查询不允许成为准备好的语句。我在下面使用了@Mike W的代码,效果很好,但当我的代码失败时,我试图找出它为什么有效,而你的答案给了我一个指标,所以我接受了它作为真正的答案。事实证明,当使用GString时,Sql类解析GString以提取变量并从中构建一个准备好的语句,正如他所说的,改变DDL的查询不允许成为准备好的语句。所以,我不知道我在幕后使用了一份事先准备好的声明。错误消息(包含?)现在变得更有意义了。我就是这样推断准备好的语句的:语法错误中的
几乎总是表示MySQL中未正确解析、准备好的语句。我在下面使用了@Mike W的代码,效果很好,但当我的代码失败时,我试图找出它为什么有效,而你的答案给了我一个指标,所以我接受了它作为真正的答案。事实证明,当使用GString时,Sql类解析GString以提取变量并从中构建一个准备好的语句,正如他所说的,改变DDL的查询不允许成为准备好的语句。所以,我不知道我在幕后使用了一份事先准备好的声明。错误消息(包含?)现在变得更有意义了。这就是我如何推断prepared语句的:语法错误中的
几乎总是表示mysql中未正确解析的prepared语句