MS Access currentdb.excute 的结果与 Docmd.RunSQL 不同

Posted

技术标签:

【中文标题】MS Access currentdb.excute 的结果与 Docmd.RunSQL 不同【英文标题】:MS Access currentdb.excute has different result than Docmd.RunSQL 【发布时间】:2017-03-28 13:45:27 【问题描述】:

我使用 VBA 运行带有 Currentdb.Execute 命令的 INSERT INTO ... SELECT... SQL 查询。但是,我对结果有疑问。有一些行缺少数据。

使用 Docmd.RunSQL 和相同的 SQL 时结果是正确的,但我不希望出现向表中插入数据的警告消息。

我还尝试仅使用 SELECT... 和 Currentdb.Execute 并在调试窗口上打印结果。结果是正确的,没有丢失数据。

这是我的代码:

strsql = strsql & "INSERT INTO tempLineItems (OrderNo, PositionNo, PartNo, [Description], PlannedDeliveryDate, Qty, Unit, Price, Curr, txta, LineItemText, Discount, Tax) "
strsql = strsql & "SELECT dbo_ttdsls041600.t_orno, dbo_ttdsls041600.t_pono, dbo_ttdsls041600.t_item, IIF(dbo_ttipcs021600.t_dsca is null,dbo_ttiitm001600.t_dsca,dbo_ttipcs021600.t_dsca) AS t_dsca, dbo_ttdsls041600.t_ddta, dbo_ttdsls041600.t_oqua, dbo_ttdsls041600.t_cups, dbo_ttdsls041600.t_pric, dbo_ttdsls040600.t_ccur, dbo_ttdsls041600.t_txta, Null AS LineItemText, dbo_ttdsls041600.t_disc_1, dbo_ttdsls041600.t_cvat "
strsql = strsql & "FROM dbo_ttdsls040600 INNER JOIN ((dbo_ttipcs021600 RIGHT JOIN dbo_ttdsls041600 ON (dbo_ttipcs021600.t_item = dbo_ttdsls041600.t_item) AND (dbo_ttipcs021600.t_cprj = dbo_ttdsls041600.t_cprj)) LEFT JOIN dbo_ttiitm001600 ON dbo_ttdsls041600.t_item = dbo_ttiitm001600.t_item) ON dbo_ttdsls040600.t_orno = dbo_ttdsls041600.t_orno "
strsql = strsql & "WHERE (((dbo_ttdsls041600.t_orno)=" & Me.txtSalesOrderNo.Value & ") AND ((dbo_ttdsls041600.t_pono)>0)) "
strsql = strsql & "ORDER BY dbo_ttdsls041600.t_pono;"

问题出在

IIF(dbo_ttipcs021600.t_dsca is null,dbo_ttiitm001600.t_dsca,dbo_ttipcs021600.t_dsca) AS t_dsca

我使用了 ISNULL() 函数,结果与使用 Is Null 相同

2017 年 3 月 28 日更新: 这些表是来自 SQL Server 的链接表。我根据这些链接的子集数据创建了本地表,并且根本没有丢失数据。

【问题讨论】:

或者只使用NZ(dbo_ttipcs021600.t_dsca,dbo_ttiitm001600.t_dsca) 并节省一些按键操作。 我尝试了 NZ() 函数,但结果与丢失数据相同。 你为什么要为 t_item 取别名,尤其是它自己的名字?记录已插入,但描述字段中缺少数据?还有其他人吗?想要提供样本数据进行测试?我推荐 Box.com 文件共享网站。 我之前必须对 t_item 做一些事情,并且在我改回来时没有删除它。这些表是SQL server的链接表,我会尝试创建一个本地表,看看问题是否仍然存在。 我根据这些链接的子集数据创建了本地表,并且根本没有丢失数据。 【参考方案1】:

很奇怪。但我从来不用大量使用 SQLServer 表。要使用 RunSQL 而不会收到警告,请将其关闭再打开。

DoCmd.SetWarnings False
DoCmd.RunSQL ...
DoCmd.SetWarnings True

【讨论】:

【参考方案2】:

我只是对这个问题很好奇,所以我通过使用多层查询做了不同的方法。

strsql = strsql & "INSERT INTO tempLineItems (OrderNo, PositionNo, PartNo, Description, PlannedDeliveryDate, Qty, Unit, Price, Curr, txta, LineItemText, Discount, Tax) "
strsql = strsql & "SELECT SO1.t_orno, SO1.t_pono, SO1.t_item, nz(SO1.t_dsca, dbo_ttiitm001600.t_dsca) AS t_dsca, SO1.t_ddta, SO1.t_oqua, SO1.t_cups, SO1.t_pric, SO1.t_ccur, SO1.t_txta, Null AS LineItemText, SO1.t_disc_1, SO1.t_cvat "
strsql = strsql & "FROM (SELECT SO.t_orno, SO.t_ccur, SO.t_pono, SO.t_item, SO.t_oqua, SO.t_pric, SO.t_cups, SO.t_ddta, SO.t_txta, SO.t_disc_1, SO.t_cvat, dbo_ttipcs021600.t_dsca "
strsql = strsql & "FROM (SELECT dbo_ttdsls040600.t_orno, dbo_ttdsls040600.t_ccur, dbo_ttdsls041600.t_pono, dbo_ttdsls041600.t_item, dbo_ttdsls041600.t_pric, dbo_ttdsls041600.t_cups, dbo_ttdsls041600.t_ddta, dbo_ttdsls041600.t_cprj, dbo_ttdsls041600.t_txta, dbo_ttdsls041600.t_disc_1, dbo_ttdsls041600.t_cvat, dbo_ttdsls041600.t_oqua "
strsql = strsql & "FROM dbo_ttdsls041600 INNER JOIN dbo_ttdsls040600 ON dbo_ttdsls041600.t_orno = dbo_ttdsls040600.t_orno "
strsql = strsql & "WHERE (((dbo_ttdsls040600.t_orno)=" & Me.txtSalesOrderNo & "))) SO "
strsql = strsql & "LEFT JOIN dbo_ttipcs021600 ON dbo_ttipcs021600.t_cprj = SO.t_cprj AND dbo_ttipcs021600.t_item = SO.t_item)  AS SO1 LEFT JOIN dbo_ttiitm001600 ON dbo_ttiitm001600.t_item = SO1.t_item "
strsql = strsql & "ORDER BY SO1.t_pono;"

这行得通!我猜在 Access 内部有一些问题。

【讨论】:

以上是关于MS Access currentdb.excute 的结果与 Docmd.RunSQL 不同的主要内容,如果未能解决你的问题,请参考以下文章

MS ACCESS, VBA 将外部 MS Access 表导入 SQL server 表

MS Access:突出显示 MS Access 报告中的特定字段

MS access 使用相对路径查询多个 MS Access 数据库

连接 MS Access 而另一个应用程序使用相同的 MS Access 文件

将 MS Access 用作 Winform 或 WPF 的后端时如何避免损坏 MS Access

如何让 ms-access 以其他用户身份连接到 ms-sql?