我有一个使用HSQLDB的JAVAFX项目。尝试设置表的源时,我想我理解了一个异常,但是由于无法修复它,所以我想我不理解它。我的SQL是:
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拆分为Strings的ArrayList,每一行都是一个元素。所以我得到了这个Java代码:
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);以下异常而失败:
PreparedStatement ps = c.prepareStatement(sql);
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");在语义上可能并不完全正确,但是从语法上讲应该可以使用,并且由于错误早于此,因此不应导致此错误。当我在没有该行的情况下运行该应用程序时,会发生相同的错误。
ps.setString(1, path.toUri().toString() + ";encoding=UTF-8;ignore_first=false;fs=\\n\\r");
所以我的问题是:怎么了SET TABLE temp SOURCE ?;?为什么我不能将其用作Java中的PreparedStatement?当我从理解文档的语法是SET TABLE <tablename> SOURCE <quoted_filename_and_options>这里<quoted_filename_and_options>是一个字符串。难道我用Java准备了吗?
SET TABLE temp SOURCE ?;
SET TABLE <tablename> SOURCE <quoted_filename_and_options>
<quoted_filename_and_options>
将PreparedStatement发送到基础SQL引擎进行编译。允许使用参数的位置取决于驱动程序和引擎。通常仅在非常特定的位置支持它们,否则将无法真正编译语句。
考虑一个仅包含“?”的PreparedStatement,并提供一个参数:
ps.setString(1, "SELECT * FROM myTable");
无法编译,因此被拒绝。
因此,大多数SQL数据库仅在通常会出现简单值的位置中支持INSERT / UPDATE / SELECTS中的参数。它们不能用于字段名称,表名称等。