Errore quando si usa il cursore client per aggiungere record a SQL Server tabella con valore predefinito nel campo Datetime

Questo articolo consente di risolvere il problema che si verifica quando si usa il cursore client per aggiungere record a SQL Server tabella con valore predefinito nel campo Datetime.

Versione originale del prodotto: SQL Server
Numero KB originale: 279888

Sintomi

Se si usa ADO per inserire un nuovo record tramite un recordset sul lato client in una tabella SQL Server con un campo non nullable datetime con un valore predefinito, viene visualizzato il messaggio di errore seguente se non si specifica un valore per il datetime campo:

Errore di runtime '-2147217887 (80040e21)': errori generati dall'operazione in più passaggi. Controllare ogni valore di stato.

Questo errore si verifica se si utilizza il provider OLE DB per SQL Server o il provider OLE DB per i driver ODBC. Il messaggio di errore potrebbe essere diverso quando si usa Microsoft Data Access Components (MDAC) versione 2.5 Service Pack 1 (SP1) o versioni precedenti. Questo errore non si verifica con un cursore sul lato server.

Causa

Questo errore si verifica nel motore cursore client quando tenta di convertire il valore di tipo DBTYPE_DBTIMESTAMP in DBTYPE_VARIANT.

Risoluzione

Esistono diversi modi per risolvere questo problema:

  • Utilizzare un cursore sul lato server per il recordset.
  • Rimuovere il valore predefinito specificato per il campo nel database.
  • Specificare sempre un valore per il campo quando si aggiunge un nuovo record.

Passaggi per riprodurre il comportamento

  1. Aggiungere una tabella a SQL Server che contiene un campo datetime che non accetta valori Null e che ha un valore predefinito. Includere almeno un campo aggiuntivo. Ai fini di questo articolo, viene creata la tabella SQL Server 2000 seguente:

    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. Per inserire una riga nella tabella, eseguire codice simile al codice seguente.

    Nota

    Prima di eseguire questo codice, è necessario modificare l'ID utente =<UID> e la password =<password> complessa con i valori corretti. Assicurarsi che <UID> disponga delle autorizzazioni appropriate per eseguire questa operazione nel database. Assicurarsi inoltre di non specificare un valore per il datetime campo.

     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
    

    Quando si esamina la proprietà Value del campo, viene visualizzato il datetime messaggio di errore sopra indicato.