无法在 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 中执行更新语句的主要内容,如果未能解决你的问题,请参考以下文章
使用 Java 和 UCanAccess 更新备注字段中的日期时间和字符串
oracle存储过程中update语句一直在执行中,无法更新完成
UCanAccess/Jackcess 在 Access 中创建查看/保存查询
java.Sql.SQLException,无法加载类 net.ucanaccess.jdbc.UcanaccessDriver