我正在尝试使用 PreparedStatement 将记录插入 Oracle 数据库,但我只收到此错误。在这一点上,我克服它的努力远远超过了我的进步,所以另一双眼睛可能会有所帮助。无效字符在哪里?
很多我发现的东西都表明你的 sql 字符串中尾随的“;
”可能是罪魁祸首,但我没有我从一开始就声明。
我的连接本身,它在程序的其他几个地方工作完美:
Properties props = new Properties();
props.setProperty( "user", username );
props.setProperty( "password", password );
props.setProperty( "defaultRowPrefetch", "10" );
props.setProperty( "defaultBatchValue", "10" );
props.setProperty( "processEscapes", "false" );
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection(DB_URL_SVC, props);
我想要完成它的方式(除了我将它包装在一个接受三个字符串的方法中)但是它抛出一个 SQLSyntaxErrorException
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); // ORA-00911: invalid character error
这有效,但由于参数是硬编码的,所以违背了使用 PreparedStatement 的目的:
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( 'JHT' , 'USA' , '2500' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.executeUpdate();
有效。但是,我知道用单引号和双引号连接变量也不是最好的方法,因为 PreparedStatement 应该让我们不必处理这部分语法:
String value1 = "JHT";
String value2 = "USA";
int value3 = 2500;
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '" + value1 + "', '" + value2 + "', '" + value3 + "' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.executeUpdate();
失败并出现 SQLSyntaxErrorException。所以即使我自己引用代码语法,我仍然无法将这些变量放在 preStatement.setString() 中,这至少允许一点灵 active 。
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "' + value1 + '");
preStatement.setString(2, "' + value2 + '");
preStatement.setInt(3, "' + value3 + '");
preStatement.executeUpdate(); // ORA-00911: invalid character error
失败。用单引号将我的字符串中的占位符引起 SQLException。
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '?' , '?' , '?' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); // invalid column index
失败。用单引号将我的字符串中的两个 String
(但不是 int
)占位符引起 SQLException.
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '?' , '?' , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); // invalid column index
这不会失败,但也不会写入数据库(即使我没有禁用自动提交)。
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeBatch();
我还尝试了所有使用反斜杠、双反斜杠、反引号、quitsies, no-startsies, erasies, double-stamps, and tofus-make-it-true 进行转义的方法!也许外面有人知道可以帮助我的巫术?!
最佳答案
你有 props.setProperty( "processEscapes", "false");
的原因吗?
我相信这会关闭使用 ?
作为绑定(bind)参数占位符的能力。我相信,如果启用了转义处理,JDBC 会在将 SQL 字符串传递给 Oracle 之前对 ?
占位符执行一些“魔术”操作。否则,?
字符将按原样发送到数据库。
偶尔会使用禁用转义处理。我在 a previous answer 中使用了它涉及密码中的 ?
字符的问题。我相信它可以在连接或语句级别禁用;要在 PreparedStatement 上重新启用转义处理,请尝试调用 preStatement.setEscapeProcessing(true);
。我希望您的第一个失败示例能够成功使用此选项集。
至于您的失败示例,那些未转义的 ?
会导致问题,因为 ?
在 SQL 中不是有效字符。将 ?
括在单引号中会将其变成单字符字符串,因此即使启用了转义处理,它也不会成为绑定(bind)参数。我不能说为什么最后一个不写入数据库。
关于java - SQL语法错误异常 : ORA-00911: invalid character,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15711573/