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

问题描述 投票:3回答:2

这个简单的VBA语句不能按预期工作:

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

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

如果我在SSMS中运行此语句或作为Access查询,它可以工作。

如果我在VBA语句中使用一个变量...“SET Number of Blocks =”和unBlocks Reserved&“,......,它可以工作。

常量工作:......“SET NumberOfBlocks = 555”......

这个也适用:NumberOfBlocks =(BlocksReserved * 1)

NumberOfBlocks和BlocksReserved都是smallint而不是null;该记录有一个时间戳/ rowversion字段。

环境:使用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] [timestamp] NOT NULL
  3. 将ID设置为主键,链接SQL表,在两者中输入测试数据。
  4. 在两个表上运行完全相同的代码(仅更改了表名): Dim strSQl As String strSQl =“UPDATE Inventory SET NumberOfBlocks = BlocksReserved,LastUser ='Me';” CurrentDb.Execute strSQl,dbFailOnError + dbSeeChanges

结果:

本地访问表:NumberOfBlocks = BlocksReserved,LastUser ='Me'

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


更多说明:

  • 将SQL Server中的数据类型更改为int(而不是smallint)并没有什么区别。
  • 但是,显式转换字段工作: ... SET NumberOfBlocks = CInt(BlocksReserved)...
  • 就像 ... SET NumberOfBlocks =(BlocksReserved * 1)...

我想,这会把我的帖子从一个问题变成一个单挑......

sql-server ms-access access-vba sql-update sqldatatypes
2个回答
1
投票

进一步测试证实,在以下条件下,这是执行命令中的错误:

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

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

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

经过测试的解决方法:

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

1
投票

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

但只有在(n)VARCHAR列包含在UPDATE查询中时! 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')

访问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 |
+----+-----------+-----------+-----------+-----------+-----------------+
© www.soinside.com 2019 - 2024. All rights reserved.