使用客户端游标将记录添加到在 Datetime 字段中具有默认值的 SQL Server 表时出现错误

本文帮助您解决在使用客户端游标将记录添加到 "日期/时间" 字段中具有默认值的 SQL Server 表时出现的问题。

原始产品版本:   SQL Server
原始 KB 数:   279888

症状

如果使用 ADO 将新记录通过客户端 recordset 插入到 SQL Server 表中,并且该表包含具有默认值的不可为 null 的 datetime 字段,则当您没有为该字段提供值时,将收到以下错误消息 datetime

运行时错误 "-2147217887 (80040e21) ":多步骤操作生成错误。 检查每个状态值。

无论您是为 SQL Server 使用 OLE DB 提供程序,还是使用 OLE DB Provider for ODBC 驱动程序,都会发生此错误。 使用 Microsoft 数据访问组件 (MDAC) 版本 2.5 Service Pack 1 (SP1) 或更早版本时,可能会有不同的错误消息。 服务器端游标不会发生此错误。

原因

当客户端游标引擎尝试将类型的值转换为时,将发生此 DBTYPE_DBTIMESTAMP 错误 DBTYPE_VARIANT

解决方案

有几种方法可以解决此问题:

  • 对 recordset 使用服务器端游标。
  • 删除为数据库中的字段指定的默认值。
  • 添加新记录时,请始终为该字段指定一个值。

再现行为的步骤

  1. 向 SQL Server 添加一个表,其中包含不接受 null 且具有默认值的 datetime 字段。 至少包含一个附加字段。 在本文中,将创建以下 SQL Server 2000 表:

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DateTest]')
    and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[DateTest]
    GO
    
    CREATE TABLE [dbo].[DateTest] ([DateId] [int] IDENTITY (1, 1) NOT NULL ,
    [TestDate] [datetime] NOT NULL ,
    [Nonsense] [varchar] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
    ) ON [PRIMARY]
    GO
    
    ALTER TABLE [dbo].[DateTest] WITH NOCHECK ADD 
    CONSTRAINT [DF_DateTest_TestDate] DEFAULT ('3/1/2001') FOR [TestDate],
     PRIMARY KEY CLUSTERED 
    ([DateId]
    ) ON [PRIMARY] 
    GO
    
  2. 若要在表中插入行,请运行与以下代码类似的代码。

    备注

    在运行此代码之前,必须将用户 ID = <UID> 和密码为更改 <strong password> 为正确的值。 请确保 <UID> 具有对数据库执行此操作的相应权限。 此外,请确保没有为该字段提供值 datetime

     Dim cnn As ADODB.Connection
     Dim rst As ADODB.Recordset
    
    Set cnn = New ADODB.Connection
    cnn.Open "Provider=SQLOLEDB;Data Source=(local);" & _
    "Initial Catalog=test;User Id=<UID>;Password=<strong password>;"
    
    Set rst = New ADODB.Recordset
    With rst
    .CursorLocation = adUseClient
    .Open "SELECT * FROM DateTest", cnn, adOpenStatic, adLockOptimistic
    
    .AddNew
    .Fields("Nonsense").Value = "test data"
    .Update
    End With
    
    Debug.Print rst("TestDate").Value
    

    当您检查字段的 Value 属性时,您会收到上面提到的错误消息 datetime