Errore quando si utilizza il cursore client per aggiungere un record a una tabella di SQL Server con valore predefinito nel campo DateTime

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

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

Sintomi

Se si utilizza ADO per inserire un nuovo record tramite un oggetto recordset sul fianco client in una tabella di SQL Server con un campo non Nullable datetime con un valore predefinito, verrà visualizzato il seguente messaggio di errore se non si specifica un valore per il datetime campo:

Errore di run-time '-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 può variare quando si utilizza Microsoft Data Access Components (MDAC) versione 2,5 Service Pack 1 (SP1) o versioni precedenti. Questo errore non si verifica con un cursore sul fianco del server.

Causa

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

Risoluzione

Esistono diversi modi per ovviare a questo problema:

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

Procedura per la riproduzione del 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. Per il bene di questo articolo, viene creata la seguente tabella di 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. Per inserire una riga nella tabella, eseguire codice analogo al codice seguente.

    Nota

    Prima di eseguire questo codice, è necessario modificare l'ID utente = <UID> e la password = <strong password> nei valori corretti. Verificare che <UID> disponga delle autorizzazioni appropriate per eseguire l'operazione sul 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
    

    Viene visualizzato il messaggio di errore sopra menzionato quando si esamina la proprietà Value del datetime campo.