2017-03-18 10 views
0

ここで構文エラーが発生する可能性があります。ここでは、コードは次のようになります。私はそれを実行したときにここでgroovy CREATE DATABASEを使用したMySQLSyntaxErrorExceptionが存在しない場合

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) 

何が問題になりますか?

答えて

1

問題は、prepared statementsを使用してこのステートメントを実行しようとしていることです。ただし、DDL命令(データベースの作成など)は、データベース名を変数にバインドできないため、プリペアドステートメント内では使用できません。

具体的なケースで可能なこと:準備済みのステートメントを使用せずに直接クエリを構築します。

私はこれでより正確にする必要があります:実際には:DDL文はを使用すると、データベース、テーブルやカラム名などの名前に変数をバインドすることはできません、準備された文では使用できですが。しかし、私はそれをテストしていませんが、デフォルト値やセットアップパラメータ値などの他のものに変数をバインドすることはできます。

+0

魅力的なを使用してテスト

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

。私は以下の@Mike Wのコードを使っていましたが、うまくいきましたが、私が失敗したときに働いた理由を理解しようとしていました。 GStringを使用するとき、SqlクラスはGStringを解析して変数を抽出し、そこからプリペアドステートメントを作成し、DDLを変更するクエリはプリペアドステートメントではないことが判明しました。だから、舞台裏で準備された声明を使っていたことは知らなかった。エラーメッセージ(?が入っています)は、今、SOをはるかに意味を持ちます。 –

+0

それは私が準備したステートメントを導き出す方法です:構文エラー内の '? 'は、mysqlの適切に解決され準備されたステートメントをほぼ常に示しています。 – Psi

1

executeではなくexecuteUpdateを使用し、呼び出しでGStringを使用しないでください。この前に文字列を解決してください。これはSQLインジェクションから保護するためだと思います。 MySQLバージョン5.7.17

+0

魅惑的です。このコードはうまくいきました。ありがとうございました。私は鉱山が失敗し、@ Psiの答えが私に指標を与えたときに働く理由を理解しようとしていました。 GStringを使用するとき、SqlクラスはGStringを解析して変数を抽出し、そこからプリペアドステートメントを作成し、DDLを変更するクエリはプリペアドステートメントではないことが判明しました。 –

関連する問題