我试图在我的战争中访问一个SQLLite数据库,其中一些列的名称中有空格。
我在SO上看到了上一个问题Read data from SQLite where column name contains spaces,但解决方案不起作用:
我知道我应该用``,“”或[]来逃避列名称,但这对我来说都不起作用,我得到以下每个转义字符的异常,空格或没有空格在列名称中:
java.sql.SQLException: no such column: '[class of worker]'
java.sql.SQLException: no such column: '"age"'
与`相同,并且在SO上没有很好地逃脱
同时,该请求适用于没有空格的未转义列名称(例如“年龄”或“教育”)
我的代码中的请求看起来很好:
SELECT DISTINCT `class of worker`, COUNT(*) as countt, ROUND(CAST(SUM(age) AS FLOAT)/COUNT(*),3) as avgage FROM census_learn_sql GROUP BY `class of worker` ORDER BY countt DESC
这是访问db的代码:
public Results getColumnValues(String column){
column = "`" + column + "`"; //handle space in column names
String sql = "SELECT DISTINCT "+column+", COUNT(*) as countt, ROUND(CAST(SUM(age) AS FLOAT)/COUNT(*),3) as avgage FROM census_learn_sql GROUP BY "
+column+" ORDER BY countt DESC";
Results results = new Results();
int count = 0;
int clippedOutRows = 0;
try (Connection conn = this.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)){
while (rs.next()) {
if (count >= 100){
clippedOutRows += rs.getInt("countt");
}
else {
results.getResults().add(new RowResult(rs.getString(column),
rs.getInt("countt"),
rs.getDouble("avgage")));
}
count++;
}
results.setClippedOutRows(clippedOutRows);
results.setClippedOutValues(count > 99 ? count - 99 : 0);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return results;
}
这是我的pom文件依赖项:
<properties>
<!-- maven-compiler-plugin -->
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<version.javaee>7.0</version.javaee>
<version.resteasy>3.0.10.Final</version.resteasy>
<version.jackson>2.4.1</version.jackson>
<version.junit>4.11</version.junit>
<version.assertj>1.6.1</version.assertj>
<version.commons>3.2.1</version.commons>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${version.resteasy}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>${version.resteasy}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>${version.resteasy}</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${version.javaee}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${version.commons}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<!-- SQLite JDBC library -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.8.11.2</version>
</dependency>
</dependencies>
我不知道我在这里做错了什么,这是一个依赖性问题吗?
提前感谢您的帮助
答案 0 :(得分:3)
您正在修改字符串值column
以分隔列名
column = "`" + column + "`"; //handle space in column names
String sql = "SELECT DISTINCT "+column+", COUNT(*) ...
但是当您从ResultSet中检索值时,您使用的是分隔列名称
rs.getString(column)
相当于
rs.getString("`class of worker`")
并且ResultSet不包含该名称的列:名称只是class of worker
。换句话说,SQL命令需要分隔符,但ResultSet#getString
方法不需要。
因此,不应修改column
变量,而应该在sql
字符串中放置反引号(或双引号或方括号; SQLite支持所有这些)
// column = "`" + column + "`"; // do not handle space in column names here, do it below
String sql = "SELECT DISTINCT `" + column + "`, COUNT(*) ...
然后你的rs.getString(column)
应该可以正常工作。