使用SQL Server后端更新的MS Access失败,没有错误

时间:2019-03-21 01:04:05

标签: sql-server ms-access access-vba sql-update sqldatatypes

此简单的VBA语句无法按预期工作:

strSQl = "UPDATE Inventory SET NumberOfBlocks = BlocksReserved, LastUser = 'Me' WHERE InventoryID = 1234;"
CurrentDb.Execute strSQl, dbFailOnError + dbSeeChanges

LastUser已更新,但NumberOfBlocks保持不变,没有错误。

如果我在SSMS中或作为Access查询运行此语句,它将起作用。

如果我在VBA语句中使用了一个变量……“ SET NumberOfBlocks =”&intBlocksReserved&“,...,那么它就可以工作。

恒定工作:...“ SET NumberOfBlocks = 555” ...

这一项同样可行:NumberOfBlocks =(BlocksReserved * 1)

NumberOfBlocks和BlocksReserved均为smallint且不为null;该记录具有时间戳/行版本字段。

环境:使用SQL 2016后端访问2016。

有什么想法为什么我的最初声明会默默地失败?谢谢!


更多测试证实了我以前的发现:

  1. 创建了一个新的Access数据库,表清单:ID(自动编号,PK),NumberOfBlocks(整数),BlocksReserved(整数),LastUser(短文本10)
  2. 在SQL Server中创建了一个表:

    [ID] [int] IDENTITY(1,1)NOT NULL, [NumberOfBlocks] [smallint] NULL, [BlocksReserved] [smallint] NULL, [LastUser] nvarchar为NULL, [RV] [时间戳记]不为空

  3. 将ID设置为主键,链接SQL表,并在两者中输入测试数据。

  4. 在两个表上运行完全相同的代码(仅更改了表名):

    将strSQl设置为字符串

    strSQl =“更新库存设置NumberOfBlocks =保留的块,LastUser ='我';” CurrentDb。执行strSQl,dbFailOnError + dbSeeChanges

结果:

本地访问表:NumberOfBlocks =保留的块,LastUser ='Me'

链接的SQL表:NumberOfBlocks不变,LastUser ='Me'


更多说明:

  • 将SQL Server中的数据类型更改为int(而不是smallint)没有任何作用。
  • 但是,显式转换字段有效:

    ... SET NumberOfBlocks = CInt(BlocksReserved)...

  • 就像

    ... SET NumberOfBlocks =(保留的块数* 1)...

我想,那把我的帖子从一个问题变成了一个提醒……

2 个答案:

答案 0 :(得分:1)

进一步的测试证实,在以下情况下,这是 Execute命令中的错误:

  • 这是一条UPDATE语句,其中一个整数字段分配给另一个整数字段,例如 SET FieldA = FieldB (相同的数字数据类型)
  • 这是SQL Server中的链接表。

相同的SQL语句可以正常工作

  • 在Access中具有表或
  • 在查询中使用时。

经过测试的解决方法:

  • 明确转换字段:SET FieldA = CInt(FieldB)...(或CLng ...)
  • 使用任何计算:SET FieldA = FieldB * 1
  • 使用变量:SET FieldA =“&intFieldB

答案 1 :(得分:1)

这很有趣。我可以使用Access 2010,SQL Server 2008 R2和SQL Server的ODBC驱动程序17来重现它。

,如果UPDATE查询中包含(N)VARCHAR列!
UPDATE AAA SET Smallint2 = Smallint1, Int2 = Int1;有效。

CREATE TABLE AAA (
    ID int IDENTITY(1,1) NOT NULL, 
    Smallint1 SMALLINT NULL, 
    Smallint2 SMALLINT NULL, 
    Int1 INT NULL,
    Int2 INT NULL,
    foo NVARCHAR(255) NULL,
    RV TIMESTAMP NOT NULL,

    CONSTRAINT PK_AAA PRIMARY KEY (ID)
)
GO

INSERT AAA (Smallint1, Smallint2, Int1, Int2, foo) 
VALUES (1, 0, 77, 9999, 'asdf'), 
       (3456, NULL, NULL, 1234, 'null')

Access-VBA:

Sub TestAAA()

    Dim strSql As String

    strSql = "UPDATE AAA SET Smallint2 = Smallint1, Int2 = Int1;"
    CurrentDb.Execute strSql, dbFailOnError + dbSeeChanges

    Stop
    ' Requery table => UPDATE was successful!

    ' Edit and save values in Smallint1 / Int1

    strSql = "UPDATE AAA SET Smallint2 = Smallint1, Int2 = Int1, foo = 'with NVARCHAR';"
    CurrentDb.Execute strSql, dbFailOnError + dbSeeChanges

    Stop
    ' Requery => Smallint2 / Int2 are not updated, "foo" is!

    strSql = "UPDATE AAA SET Smallint2 = CInt(Smallint1), Int2 = CLng(Int1), foo = 'with Conversion';"
    CurrentDb.Execute strSql, dbFailOnError + dbSeeChanges

    ' Requery => Smallint2 / Int2 are updated!

End Sub

结果:

  • 初始状态
  • 第一次更新后
  • 手动编辑并第二次更新后
  • 第三次更新后
+----+-----------+-----------+-----------+-----------+-----------------+
| ID | Smallint1 | Smallint2 |   Int1    |   Int2    |       foo       |
+----+-----------+-----------+-----------+-----------+-----------------+
| 1  | 1         | 0         | 77        | 9999      | asdf            |
| 2  | 3456      |           |           | 1234      | null            |
|    |           |           |           |           |                 |
| ID | Smallint1 | Smallint2 | Int1      | Int2      | foo             |
| 1  | 1         | 1         | 77        | 77        | asdf            |
| 2  | 3456      | 3456      |           |           | null            |
|    |           |           |           |           |                 |
| ID | Smallint1 | Smallint2 | Int1      | Int2      | foo             |
| 1  | 222       | 1         | 988888888 | 77        | with NVARCHAR   |
| 2  | 333       | 3456      | 999999999 |           | with NVARCHAR   |
|    |           |           |           |           |                 |
| ID | Smallint1 | Smallint2 | Int1      | Int2      | foo             |
| 1  | 222       | 222       | 988888888 | 988888888 | with Conversion |
| 2  | 333       | 333       | 999999999 | 999999999 | with Conversion |
+----+-----------+-----------+-----------+-----------+-----------------+