2017-02-14 28 views
0

私はHSQLDBを使ったJAVAFXプロジェクトを持っています。テーブルのソースを設定しようとすると、私は例外が発生すると私は理解すると思うが、私はそれを修正できないので、私はそれを理解していないと思う。 私のSQLは次のとおりです。HSQLDB予期しないトークン:

DROP TABLE temp IF EXISTS; 
CREATE TEXT TABLE temp(text_data LONGVARCHAR(10000)); 
SET TABLE temp SOURCE ?; 
INSERT INTO log(typ, json) SELECT SUBSTRING(text_data, 3, LOCATE('"', text_data, 3)-3),text_data FROM temp WHERE text_data <> ''; 
DROP TABLE temp IF EXISTS; 

Mutlipleステートメントは何とかここに私のために動作しません、これは今のところ問題になることはありません。上記のsqlをStringのArrayListに分割し、各行は1つの要素になります。

s = c.createStatement(); 
for (String sql : sqls) { 
    System.out.println("sql: " + sql); 
    if (sql.contains("?")) { 
    System.out.println("in ? part"); 
    PreparedStatement ps = c.prepareStatement(sql); 

    ps.setString(1, path.toUri().toString() + ";encoding=UTF-8;ignore_first=false;fs=\\n\\r"); 
    System.out.println("ps prepared" + ps.toString()); 
    ps.execute(); 
    } else { 
    s.execute(sql); 
    } 
} 

そして、私のアプリケーションは、以下の例外を除いてライン PreparedStatement ps = c.prepareStatement(sql);で失敗している:だから私は、このJavaコードを持って前に、この出力で

java.sql.SQLSyntaxErrorException: unexpected token: ? in statement [SET TABLE temp SOURCE ?;] 
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) 
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source) 
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source) 
    at myfile in the line I pointed out above 
    at anotherofmyfiles 
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.hsqldb.HsqlException: unexpected token: ? 
    at org.hsqldb.error.Error.parseError(Unknown Source) 
    at org.hsqldb.ParserBase.unexpectedToken(Unknown Source) 
    at org.hsqldb.ParserBase.checkIsValue(Unknown Source) 
    at org.hsqldb.ParserBase.readQuotedString(Unknown Source) 
    at org.hsqldb.ParserCommand.compileTableSource(Unknown Source) 
    at org.hsqldb.ParserCommand.compileSetTable(Unknown Source) 
    at org.hsqldb.ParserCommand.compileSet(Unknown Source) 
    at org.hsqldb.ParserCommand.compilePart(Unknown Source) 
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source) 
    at org.hsqldb.Session.compileStatement(Unknown Source) 
    at org.hsqldb.StatementManager.compile(Unknown Source) 
    at org.hsqldb.Session.execute(Unknown Source) 
    ... 7 more 

sql: DROP TABLE temp IF EXISTS; 
sql: CREATE TEXT TABLE temp(text_data LONGVARCHAR(10000)); 
sql: SET TABLE temp SOURCE ?; 
in ? part 

私は承知していますps.setString(1, path.toUri().toString() + ";encoding=UTF-8;ignore_first=false;fs=\\n\\r");はセマンティクスでは完全ではないかもしれませんが、構文的にはうまくいくはずです。その前にエラーがあるので、このエラーの原因であってはなりません。私は、その行なしでアプリケーションを実行しているときに同じエラーが発生します。

私の質問です。SET TABLE temp SOURCE ?;で何が問題になっていますか?なぜ私はJavaのPreparedStatementとしてこれを使用しないのですか? documentationからわかるように、構文はSET TABLE <tablename> SOURCE <quoted_filename_and_options>です。<quoted_filename_and_options>は文字列です。私はJavaでそれを準備していますか?

答えて

1

PreparedStatementは、コンパイルのために基礎となるSQLエンジンに送信されます。パラメータを使用できる場所は、ドライバとエンジンによって異なります。通常、それらは非常に特定の場所でのみサポートされています。そうでないと、実際にはステートメントをコンパイルできません。 「?」

にのみ含まれていることをPreparedStatementを考えてみましょう、そしてあなたは、パラメータを指定:

ps.setString(1, "SELECT * FROM myTable"); 

これはコンパイルすることができないので、それは拒否されます。

したがって、ほとんどのSQLデータベースは、単純な値が通常表示される位置のINSERT/UPDATE/SELECTSのパラメータのみをサポートしています。フィールド名やテーブル名などには使用できません。

+0

これは良い点です。ありがとうございます。私はあなたが私の質問に答えたので、私はこれを答えとしてマークすると思います。テーブルのSOURCEをパラメータとして設定する方法がありますか? – Sebu

+0

あなた自身の '? 'を置き換える明白なアプローチはうまくいくでしょうが、Stringがどこから来ているかに応じてSQLインジェクション攻撃をあなたに残すかもしれません。そのような目的には使用できないことを確認するために入力を最初にサニタイズする必要があります。通常これを行う方法は、たとえば正規表現を使用してそこに置くことを許可されているものを厳密に制限することです。 – john16384

+0

それは私のために働く。ジョンさんありがとう – Sebu

関連する問題