2011-09-22 181 views
2

我有一个预生成的CSV文件,我需要运行SQL查询。我一直在寻找不同的开源解决方案(例如CsvJdbc,xlSQL等),但还没有真正找到令人满意的东西。使用HSQLDB JDBC驱动程序的CSV SQL驱动程序

CsvJdbc无法识别ORDER BY,GROUP BY等 xlSQL仅在XLS文件上运行,而不是CSV(或者我无法使用CSV运行,任何人都知道如何?)。另外它不在开发或支持了。

我读过HSQLDB支持查询CSV文件的地方,但是我一直无法正确工作。这是我迄今为止所做的:

如果我使用HSQLDB创建CSV文件,那么它能够成功执行查询。这里是代码为:

String driver = "org.hsqldb.jdbcDriver"; 
Driver d = (Driver) Class.forName(driver).newInstance(); 
String protocol = "jdbc:hsqldb:file"; 
final String url = "jdbc:hsqldb:file:/C:/Users/varun.achar/Documents"; 

final StringBuilder createTable = new StringBuilder(); 
createTable.append("CREATE TEXT TABLE currency ("); 
createTable.append("id INT PRIMARY KEY, name VARCHAR)"); 
final StringBuilder linkTable = new StringBuilder(); 
linkTable.append("SET TABLE currency SOURCE "); 
linkTable.append("\"/currencies.csv"); 
linkTable.append(";ignore_first=true;all_quoted=true\""); 
Connection conn = DriverManager.getConnection(url, "sa", ""); 
Statement stm = conn.createStatement(); 
stm.execute(createTable.toString()); 
stm.execute(linkTable.toString()); 
ResultSet resultSet = stm.executeQuery("SELECT * FROM CURRENCY"); 
if (resultSet != null) { 
    while (resultSet.next()) { 
     System.out.println("CURRENCY = " + resultSet.getString(2)); 
    } 
} 
conn.close(); 

但同样的事情不起作用,当我删除文件,并再次运行它!我得到

表已经存在的错误:在声明中货币[CREATE TEXT TABLE货币]

而且,如果我有一个预先存在的csv文件(格式是正确的,因为我能运行使用CsvJDBC简单的SELECT语句),然后我得到的错误没有发现

表:声明RMS [SET TABLE RMS]

代码

final StringBuilder linkTable = new StringBuilder(); 
linkTable.append("SET TABLE rms SOURCE "); 
linkTable.append("\"C:/myreports/temp/user/1316083232009/rms.csv"); 
linkTable.append(";ignore_first=true;all_quoted=true\""); 
Driver d = (Driver) Class.forName(driver).newInstance(); 
System.out.println("Driver was successfully loaded."); 
String protocol = "jdbc:hsqldb:file"; 
String database = "C:\\myreports\\temp\\user\\1316083232009\\rms.csv"; 
String url = protocol + ":" + database; 
con = DriverManager.getConnection(url); 
stm = con.createStatement(); 
stm.execute(linkTable.toString()); 
resultSet = stm.executeQuery(testSQLStatement()); 
if (resultSet != null) { 
    while (resultSet.next()) { 
     System.out.println("FULL NAME = "+ resultSet.getString("usr_FULL_NAME")); 
    } 
} 

有人可以对此有所了解吗?

感谢

回答

3

单HSQLDB数据库可以有多个表,包括几个文本表。看起来你认为每个文本表必须有一个数据库,事实并非如此。

数据库路径不是目录。它也不是一个CSV文件。在你的第一个例子中,你应该指定一个这样的数据库名称:

final String url = "jdbc:hsqldb:file:/C:/Users/varun.achar/Documents/mydb"; 

在第二个例子中是一样的。

该数据库由一些以您已确定名称开头的文件组成。在本例中,您将有mydb.properties,mydb.script等。

CREATE TEXT TABLE ...语句为该表创建元数据。该表元数据被保存在数据库中。

第一个例子将起作用。如果删除CSV文件,然后打开数据库,'CREATE TEXT TABLE'语句仍然存储在数据库中,因此当您尝试再次创建同一个表时,它会发出抱怨。

如果您有一个预先存在的CVS文件,您仍然需要以CREATE TEXT TABLE ...开头,然后使用SET TABLE语句将其与CVS链接起来,方法与第一个示例相同。

+0

谢谢..我也想到了..:D –

+0

虽然我想问一下,在应用where子句之前,hsqldb是否将整个文件读入内存,或者是否有一个机制可以通过它直接在文件上执行这些操作? –

+2

它读取整个文件一次以创建索引。然后它读取选择性行。主键列有一个自动索引。如果WHERE子句位于不同的列上,则需要在该列上创建索引。在SET TABLE语句之前创建索引会更快。 – fredt