ucanaccess :带有空格的意外令牌

Posted

技术标签:

【中文标题】ucanaccess :带有空格的意外令牌【英文标题】:ucanaccess : unexpected token with spaces 【发布时间】:2015-08-20 14:31:27 【问题描述】:

今天我遇到了 Access DB、Ucanaccess 3.0 和带空格的表名的问题。

解释一下:我有一个巨大的查询并且 ucanaccess 抛出这个异常:

SQLException: UCAExc:::3.0.0 unexpected token: AIRCRAFT

所以我调查并尝试隔离这个问题,我发现了这个:

这个查询抛出异常:

SELECT [Check Task Aircraft Listing].CTAL_Item_Number
,[Check Task Aircraft Listing].CTAL_Check
,[Check Task Aircraft Listing].CTAL_Delete
,[Check Task Aircraft Listing].CTAL_Effective
,[Check Task Aircraft Listing].CTAL_CheckSelect
,[Check Table].[Aircraft]
FROM [Check Table]
INNER JOIN [Check Task Aircraft Listing] ON [Check Table].CHECK = [Check Task Aircraft Listing].CTAL_Check
WHERE (
        (([Check Task Aircraft Listing].CTAL_Effective) = True)
        AND (([Check Table].[Aircraft]) = 'XXXX')
        )

我尝试用 _ 替换空格:

SELECT [Check_Task_Aircraft_Listing].CTAL_Item_Number
    ,[Check_Task_Aircraft_Listing].CTAL_Check
    ,[Check_Task_Aircraft_Listing].CTAL_Delete
    ,[Check_Task_Aircraft_Listing].CTAL_Effective
    ,[Check_Task_Aircraft_Listing].CTAL_CheckSelect
    ,[Check_Table].[Aircraft]
FROM [Check_Table]
INNER JOIN [Check_Task_Aircraft_Listing] ON [Check_Table].CHECK = [Check_Task_Aircraft_Listing].CTAL_Check
WHERE (
        (([Check_Task_Aircraft_Listing].CTAL_Effective) = True)
        AND (([Check_Table].[Aircraft]) = 'XXXX')
        )

Ucanaccess 抛出一个新错误:

 SQLException: UCAExc:::3.0.0 user lacks privilege or object not found: CHECK_TASK_AIRCRAFT_LISTING

这是正常的:这个对象不存在。第一个异常消失了,所以我认为这是一个问题,但根据 Ucanaccess 网站,这应该可以工作:

特点:

字段名称、表名称和视图名称(访问查询)的方括号包括空格(例如,从 [my table] 中选择 [my column])。

编辑:经过更多调查,括号之间的字段/表格名称似乎可以包含一个空格,但不能包含更多

编辑2:澄清

我为了连接访问数据库我使用了一个名为 ConnectDB 的类:

String url = "jdbc:ucanaccess://D:/ADEL/ADEL Local/ADEL_DATA.accdb";
            try
            
                Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");

            
            catch (java.lang.ClassNotFoundException e)
            
                System.err.print("ClassNotFoundException: ");
                System.err.println(e.getMessage());
                ErrorFile.writeError(Thread.currentThread().getStackTrace()[2].getLineNumber(), e);
            

            try
            
                c = java.sql.DriverManager.getConnection(url);
            
            catch (SQLException e)
            
                System.err.println("SQLException: " + e.getMessage());
                ErrorFile.writeError(Thread.currentThread().getStackTrace()[2].getLineNumber(), e);
            

查看以下代码执行查询:

Connection c = ConnectDB.doConnect();
String selectString = "SELECT [Check Task Aircraft Listing].CTAL_Item_Number ,[Check Task Aircraft Listing].CTAL_Check ,[Check Task Aircraft Listing].CTAL_Delete ,[Check Task Aircraft Listing].CTAL_Effective ,[Check Task Aircraft Listing].CTAL_CheckSelect ,[CHECK TABLE].[Aircraft] FROM [CHECK TABLE] INNER JOIN [Check Task Aircraft Listing] ON [CHECK TABLE].CHECK = [Check Task Aircraft Listing].CTAL_Check WHERE ( (([Check Task Aircraft Listing].CTAL_Effective) = True) AND (([CHECK TABLE].[Aircraft]) = 'XXXX') ) ";
try
        
            stmt = c.createStatement();
            
            ResultSet data = stmt.executeQuery(selectString);
            while (data.next())
            ...use data...

第一个查询成功执行,但第二个查询失败。

【问题讨论】:

很抱歉,编辑 2 没有帮助,因为您的查询有效。也编辑了我的答案。 我尝试了一个新的数据库并且它可以工作,所以我认为我的数据库有问题但我不明白:它可以通过 ODBC:JDBC 驱动程序找到 这是因为技术堆栈完全不同,原始堆栈可能会在您的数据库的特定情况下做更多的事情。如果没有您的数据库副本,我不能再说什么,我会分析读取您的数据库并在检查任务飞机列表表上执行查询的 ucanaccess 控制台输出是什么。您确定您使用的 hsqldb 版本来自 ucanaccess 发行版吗? 【参考方案1】:

事实上你的诊断是错误的(第二次尝试没有意义,因为错误的表名导致的错误不能证明什么)。

空格的数量也完全不相关。另一个有效的例子可能是:

从 [my table bla bla bla] 中选择 [my column bla bla bla]。

我刚刚在两个名为 Check Task Aircraft ListingCheck Table 的表上尝试了您的查询(使用查询中指定的列创建),它与3.0.0。 请帮助我们通过一个重现您的问题的示例来帮助您。

编辑:尝试在没有表的新数据库上执行以下代码,它会在创建所需的表后很好地执行您的查询:

package xxx;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class UcaT 

    /**
     * @param args
     * @throws SQLException 
     */
    public static void main(String[] args) throws SQLException 
        Connection c= DriverManager.getConnection("jdbc:ucanaccess://c:\\db\\new_database_without_tables.accdb");


        String selectString = "SELECT [Check Task Aircraft Listing].CTAL_Item_Number ,[Check Task Aircraft Listing].CTAL_Check ,[Check Task Aircraft Listing].CTAL_Delete ,[Check Task Aircraft Listing].CTAL_Effective ,[Check Task Aircraft Listing].CTAL_CheckSelect ,[CHECK TABLE].[Aircraft] FROM [CHECK TABLE] INNER JOIN [Check Task Aircraft Listing] ON [CHECK TABLE].CHECK = [Check Task Aircraft Listing].CTAL_Check WHERE ( (([Check Task Aircraft Listing].CTAL_Effective) = True) AND (([CHECK TABLE].[Aircraft]) = 'XXXX') ) ";
        try
                
                    Statement stmt = c.createStatement();
                    stmt.execute("create table [Check Table] (id counter PRIMARY KEY,[CHECK] text,Aircraft text)");
                    stmt.execute("create table [Check Task Aircraft Listing] (id counter PRIMARY KEY,CTAL_Item_Number text,CTAL_Check text, CTAL_Delete text, CTAL_Effective yesno, CTAL_CheckSelect text)");
                    ResultSet data = stmt.executeQuery(selectString);
                    System.out.println("ok");

                
        catch(Exception e)
            e.printStackTrace();
        

    




【讨论】:

已编辑,希望对您有所帮助

以上是关于ucanaccess :带有空格的意外令牌的主要内容,如果未能解决你的问题,请参考以下文章

UCanAccess:来自空间的意外令牌

当别名包含某些字符时,UCanAccess 出现“意外令牌”错误

jdbc ucanaccesssqlexception ucaexc ::: 4.0 4 意外令牌:DOCTOR

异常意外令牌:SMALLINT;而自动增量主键

意外令牌:AS(使用 UCanAcces.jar)

无法使用 DBeaver 和默认的 UCanAccess-5.0.0 驱动程序连接到 MS Access mdb 文件