2011-09-22 180 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