BOGUE : Erreur lors de l’utilisation d’un curseur Client pour ajouter un enregistrement à la Table SQL Server qui a la valeur par défaut dans le champ date/heure


Symptômes


Si vous utilisez ADO pour insérer un nouvel enregistrement dans un jeu d’enregistrements côté client dans une table SQL Server qui dispose d’un champ datetime non nullable avec une valeur par défaut, le message d’erreur suivant s’affiche si vous ne fournissez pas de valeur pour le champ de date/heure :
Erreur d’exécution '2147217887 (80040e21)' : erreurs d’opération générée plusieurs étapes. Vérifiez chaque valeur d’état.
Cette erreur se produit si vous utilisez le fournisseur OLE DB pour SQL Server ou le fournisseur OLE DB pour pilotes ODBC. Le message d’erreur peut être différente lorsque vous utilisez des composants Microsoft Data Access (MDAC) version 2.5 Service Pack 1 (SP1) ou version antérieure. Cette erreur ne se produit pas avec un curseur côté serveur.

Cause


Cette erreur se produit dans le moteur du curseur Client lorsqu’il essaie de convertir la valeur de type DBTYPE_DBTIMESTAMP DBTYPE_VARIANT.

Résolution


Il existe plusieurs façons de contourner ce problème :
  • Utiliser un curseur côté serveur pour le jeu d’enregistrements.
  • Supprimez la valeur par défaut est spécifiée pour le champ dans la base de données.
  • Toujours spécifier une valeur pour le champ lorsque vous ajoutez un nouvel enregistrement.

État


Microsoft a confirmé qu’il s’agit d’un bogue dans les produits Microsoft répertoriés au début de cet article.

Plus d'informations


Procédure pour reproduire le comportement

  1. Ajouter une table de SQL Server qui contient un champ date/heure qui n’accepte pas les valeurs NULL et qui a une valeur par défaut. Inclure au moins un champ supplémentaire. Pour des raisons de cet article, la table de SQL Server 2000 suivante est créée :
    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. Pour insérer une ligne dans la table, exécutez le code qui est semblable au code suivant.

    Remarque Vous devez modifier l’ID utilisateur = < UID > et le mot de passe = < mot de passe fort > sur les valeurs correctes avant d’exécuter ce code. Assurez-vous que < UID > dispose des autorisations appropriées pour effectuer cette opération sur la base de données. Assurez-vous également que vous ne fournissez pas de valeur pour le champ de date/heure.
        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
    Vous recevez le message d’erreur susmentionné lorsque vous examinez la propriété de la valeur du champ datetime.