Utilisation de sql-server datetime2 avec TADOQuery.open

Je veux commencer à utiliser datetime2 champs datetime2 dans SQL Server et j'ai besoin d'insert dans les tables via ADO à partir de Delphi XE5. J'utilise TADOQuery.ExecSQL pour insert et tout fonctionne bien.

Cependant, la plupart de mes tables ont des colonnes d'identité, par exemple

 id integer identity(1,1) not null 

Pour save les allers-returns au server, j'utilise généralement Open avec deux commands dans le text de la requête.

  • La première command est l'insert
  • la deuxième command est "select scope_identity () as scope_id"

donc je peux récupérer l' identifiant nouvellement inséré dans le même aller-return.

Cela a fonctionné pour toutes mes tables, mais pas maintenant quand j'ajoute datetime2 ou la colonne de time – j'obtiens l'erreur:

Le projet "Foo.exe a déclenché l'exception EOleException avec le message" La conversion a échoué lors de la conversion de la date et / ou de l'heure à partir de la string de caractères ".

J'utilise SQL Server 2008 si cela est important. Est-ce que quelqu'un sait quel pourrait être le problème?

Le problème est que datetime2 ne revient pas aux clients ADO utilisant le fournisseur SQLOLEDB comme le type de données ADO correct ( adDBTimestamp ):

adDBTimeStamp (135)

Indique un horodatage (yyyymmddhhmmss plus une fraction en milliardièmes) (DBTYPE_DBTIMESTAMP).

Au lieu de cela, il revient en tant que string unicode ( adVarWChar ):

adVarWChar (202)

Indique une string de caractères Unicode terminée par un caractère nul.

  • 2016-11-03 12:06:01.0000000

SQL Server Native Client (SQLNCLI)

Vous pouvez essayer de passer à l'un des fournisseurs OLEDB "natifs" (par exemple SQLNCLI, SQLNCLI10, SQLNCLI11). Le problème avec ceux-ci est le suivant:

  • le client SQL Server Native ne vient pas avec le operating system (vous devez l'installer vous-même sur les ordinateurs clients)
  • le SQL Server Native Client est dérié
  • le fournisseur SQLNCLI expose des colonnes XML en tant que valeur ADO DataTypeEnum non prise en charge (141, DBTYPE_XML)
  • le fournisseur SQLNCLI expose les colonnes TIME en tant que valeur ADO DataTypeEnum non prise en charge (145)
  • le fournisseur SQLNCLI expose des colonnes UDT en tant que valeur ADO DataTypeEnum non prise en charge (132)

Vous pouvez utiliser l'option DataTypeCompatibility=80 dans votre string de connection pour que les colonnes XML returnnent comme adLongVarWChar (comme dans SQLOLEDB), mais que datetime2 , date et time returnnent sous forme de strings

Le problème avec l'utilisation DataTypeCompatibility=80 est qu'il y a un bogue dans le pilote client natif. Il convertit par erreur une colonne SQL Server DATE de adDBDate en adVarWChar :

  | SQL Server data type | SQLOLEDB | SQLNCLI | SQLNCLI w/DataTypeCompatibilyt=80 | |----------------------|-----------------|--------------------|-----------------------------------| | Xml | adLongVarWChar | 141 (DBTYPE_XML) | adLongVarChar | | datetime | adDBTimeStamp | adDBTimeStamp | adDBTimeStamp | | datetime2 | adVarWChar | adDBTimeStamp | adVarWChar | | date | adVarWChar | adDBDate | adVarWChar | | time | adVarWChar | 145 (unknown) | adVarWChar | | UDT | | 132 (DBTYPE_UDT) | adVarBinary (documented,untested) | | varchar(max) | adLongVarChar | adLongVarChar | adLongVarChar | | nvarchar(max) | adLongVarWChar | adLongVarWChar | adLongVarWChar | | varbinary(max) | adLongVarBinary | adLongVarBinary | adLongVarBinary | | timestamp | adBinary | adBinary | adBinary | 

Ce bogue dans le fournisseur SQL Native Client a été documenté sur MS Connect . Mais la personne de Microsoft, ne comprenant pas ce qu'on lui a dit, l'a fermé comme ne réparera pas .

Donc, si vous voulez vraiment utiliser un datetime2 d'ADO, vous devrez le lire comme une string , et l'parsingr vous-même.

Lecture bonus

  • MSDN: Utilisation d'ADO avec SQL Server Native Client