无法在 ucanaccess 中执行更新语句

Posted

技术标签:

【中文标题】无法在 ucanaccess 中执行更新语句【英文标题】:Unable to execute update statement in ucanaccess 【发布时间】:2015-02-05 16:39:34 【问题描述】:

我连接到 Microsoft Access 数据库。建立连接后,我将尝试从我正在使用以下查询访问的表中获取所有内容。

ResultSet rSet = stmt.executeQuery("Select * FROM DraftNightQuery")

据我所知,这很好用。然后我有一个 while 循环,只要 rSet.nex() 运行。

在我的 while 循环中,我尝试运行如下所示的更新语句:

connec.executeUpdate("UPDATE DraftNightQuery SET OwnerID='"+x+"' WHERE Last='"+split[0]+"' AND First='"+split[1]+ "' ");

它抛出了这个错误:

 net.ucanaccess.jdbc.UcanaccessSQLException: INSERT, UPDATE, DELETE or TRUNCATE not permitted for table or view

我假设它与更新查询本身有关,但它适用于 ODBC,据我在 UCanAccess 网站上的了解,它也应该适用于此。

编辑:

查询抛出PUBLIC.NZ(DOUBLE)错误的SQL:

SELECT TotalStats.ID, Players.First, Players.Last, (Nz([TotalStats].[W]*25))-(Nz([TotalStats].[L]*5))+(Nz([TotalStats].[PG]*10))+(Nz([TotalStats].[QS]*10))+(Nz([TotalStats].[SV]*20))-(Nz([TotalStats].[BS]*5))+(Nz([TotalStats].[Holds]*15))+(Nz([TotalStats].[GF]*5))+(Nz([TotalStats].[Innings]*3))-(Nz([TotalStats].[PH]*1))-(Nz([TotalStats].[ER]*2))-(Nz([TotalStats].[PHR]*8))-(Nz([TotalStats].[PBB]*3))+(Nz([TotalStats].[PK]*5))-(Nz([TotalStats].[PHB]*3))-(Nz([TotalStats].[WP]*1))+(Nz([TotalStats].[CG]*50))+(Nz([TotalStats].[ShO]*75)) AS Points, Owners.TeamName, Players.OwnerID, Players.PositionType
FROM Owners RIGHT JOIN (Players LEFT JOIN TotalStats ON Players.ID = TotalStats.ID) ON Owners.OwnerID = Players.OwnerID
WHERE (((Players.PositionType)="Pitch") AND ((Players.DraftStatus)="Drafted"))
ORDER BY (Nz([TotalStats].[W]*25))-(Nz([TotalStats].[L]*5))+(Nz([TotalStats].[PG]*10))+(Nz([TotalStats].[QS]*10))+(Nz([TotalStats].[SV]*20))-(Nz([TotalStats].[BS]*5))+(Nz([TotalStats].[Holds]*15))+(Nz([TotalStats].[GF]*5))+(Nz([TotalStats].[Innings]*3))-(Nz([TotalStats].[PH]*1))-(Nz([TotalStats].[ER]*2))-(Nz([TotalStats].[PHR]*8))-(Nz([TotalStats].[PBB]*3))+(Nz([TotalStats].[PK]*5))-(Nz([TotalStats].[PHB]*3))-(Nz([TotalStats].[WP]*1))+(Nz([TotalStats].[CG]*50))+(Nz([TotalStats].[ShO]*75)) DESC;

【问题讨论】:

查询和更新不要使用同一个语句对象。 @gknicker 我应该指定,一旦在循环中我再次说 stmt = con.createStatement。完全使用不同的变量会更好吗? 是的,当然。你还在用另一个。它支持 ResultSet。 我已将其更改为Statement connec = con.createStatement();,但仍然出现相同的错误。我还更新了我的原始帖子以反映更改后的代码。 好的,谢谢。对不起,我不知道。听起来您的访问数据库文件设置为只读,或者可能是驱动程序中的错误。 【参考方案1】:

我可以看到两个不同的问题:

-nz(double) 的问题。我刚刚实现了 nz(text),因此在下一个版本(我将尽快发布,可能在下周发布)中缺少实现。

-第二个是关于在查询中使用更新 sql 语句。 访问选择查询不是物理表,即使它们看起来像。 它们只是选择查询。 如果您对选择查询执行更新,则访问可以更新基础表中的数据:查询中使用并参与更新的表。因此,Jet 引擎可以做一些复杂的事情,如果使用不当,也可能导致糟糕和不清晰的 SQL 代码。 UCanAccess 依赖于 Hsqldb,在许多情况下不允许在视图上使用更新语句。 所以你必须直接在你要更新的表上调用SQL更新语句。

请注意,hsqldb 支持 SQL 2003 标准中的一些高级功能(如 MERGE INTO),这些功能可与 UCanAccess 一起使用,并且在某些情况下可以作为满足您要求的“智能”(但标准)替代解决方案(参见 thread )。

【讨论】:

感谢您的洞察力。我最终遵循了@GordThompson 的建议,只编辑了原始表格,这似乎做得很好。虽然 NZ(double) 错误仍然存​​在,但我目前没有尝试对该查询做任何事情,所以没什么紧迫的。【参考方案2】:

您无法使用 UCanAccess 使用标准 SELECT 查询更新结果集。你有两个选择:

    使用带有此参数的 PreparedStatement(“SELECT * FROM YourTableName”、ResultSet.TYPE_FORWARD_ONLY、ResultSet.CONCUR_UPDATABLE、ResultSet.CLOSE_CURSORS_AT_COMMIT)。执行以使用 ExecuteQuery() 生成结果集。最后,调用这两个方法更新您的结果集:UpdateString(如果字段类型是 String)和 UpdateRow。 使用 2 个语句:

    st1 = conn.createStatement();
    rs = st1.executeQuery("SELECT * FROM MyTable");
    while(rs.next()) 
        st2 = conn.createStatement();
        st2.executeUpdate("UPDATE MyTable SET MyField='New Value' WHERE MyField2 LIKE 'Condition'");
    

【讨论】:

以上是关于无法在 ucanaccess 中执行更新语句的主要内容,如果未能解决你的问题,请参考以下文章

在 Ucanaccess 中插入错误

格式化 UCanAccess 的时间字段

使用 Java 和 UCanAccess 更新备注字段中的日期时间和字符串

oracle存储过程中update语句一直在执行中,无法更新完成

UCanAccess/Jackcess 在 Access 中创建查看/保存查询

java.Sql.SQLException,无法加载类 net.ucanaccess.jdbc.UcanaccessDriver