Je travaille sur la migration d'un programme Access vers SQL Server. Voici mon code SQL extrait directement de l'accès.
Msg 257, Level 16, State 3, Line 1 Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
Comme vous pouvez le voir, j'essaie de faire une division sur une valeur datetime.
C'est l'erreur message que je reçois:
(([Promise Date])-([Date Recieved]))/100
Les deux champs sont de type Datetime. Des idées ce qui me manque?
3 Réponses :
Je pense que si j'ai raison, vous cherchez quelque chose comme ceci
SELECT DATEDIFF(day, [Promise Date], [Date Recieved])/100;
Si vous avez raison, vous pouvez obtenir plus de détails ici
p>
En fait, je pense que vous devriez inverser les deux paramètres de date
@GeorgeMenoutis Cela pourrait être
Cela a fait le travail. J'envisageais de le faire au départ, mais je pensais que j'aurais le même problème en divisant par 100. Merci @SurajKumar
Puisque DateDiff
compte les franchissements de limites (comme indiqué dans mon commentaire sur la question), la valeur est probablement quelque peu différente de celle renvoyée dans Access. Le code TSQL retournera ici le résultat de la division entière, contrairement à l'expression Access, sauf si la constante est modifiée ( 100.0
) ou un cast
(ou convert code>) est ajouté.
étant donné que les dates d'accès sont effectivement stockées en DOUBLE, je recommanderais la conversion au type flottant SQL pour gérer toutes les parties de jours
declare @x as datetime = '19960420 15:05:48'; declare @y as datetime = '19960423 18:09:23'; select (CAST(@y as float) - CAST(@x as float)) / 100 select (CAST(@y as int) - CAST(@x as int)) / 100 select datediff(day,@x,@y) / 100 select cast(datediff(day,@x,@y) as float) / 100
consultez l'exemple suivant, les différentes idées ici donnent tout à fait réponses différentes
(cast([Promise Date] as float) - cast([Date Recieved] as float))/100
L'accès doit traiter les dates comme des flottants, la partie fractionnaire représentant le temps et la partie entière représentant les jours
C'est le plus précis.
-0.0375
cela fonctionne si son accès datetime contient toujours des dates entières, mais pas si elles contiennent des composants d'heure, par exemple 2001-01-01 19:00:00 jusqu'au 2001-01-05 13:00:00 par exemple
Le message d'erreur est clair: Convertissez les valeurs de date en Double / Float, puis effectuez l'arithmétique.
Ce qui vous manque, c'est qu'il s'agit d'un non-sens syntaxique et que vous avez plus de travail à faire - et peut-être un apprentissage supplémentaire à faire avant cela. Vous devrez déterminer quel devrait être le résultat de ce calcul, puis le traduire en tsql. Je peux deviner que vous devriez utiliser datéiff pour obtenir le nombre de jours (?) Entre les dates et ensuite diviser, mais je n'ai aucune idée de ce que cela fait vraiment.
Appliquer l'arithmétique directement aux dates, en vérité, n'a guère de sens. Les dates ne sont pas des nombres, ce sont (sans surprise) des dates. Si je devais vous demander ce qu'était aujourd'hui (20190121) / 7, pourriez-vous répondre? Qu'en est-il de (la date) 20170804 * 2? Sans savoir ce que vous essayez vraiment d'accomplir ici, la réponse est difficile. Je soupçonne que les autres ont raison, que vous voulez la différence en jours / 100, et que vous devez donc utiliser
DATEDIFF
, cependant, nous devons également connaître quelques exemples de données et les résultats attendus.Si vous avez également des valeurs de temps, c'est vraiment important, comme quelque chose comme
DATEDIFF (DAY, '2019-01-20T00: 00: 00', '2019-01-21T23: 59: 59') code > est égal à 1, bien qu'il y ait essentiellement 2 jours d'intervalle, où comme
DATEDIFF (DAY, '2019-01-21T23: 59: 59', '2019-01-22T00: 00: 01'
) est 1 , malgré qu'il n'y ait que 2 secondes entre les deux dates et heures.@larnu - les dates d'accès sont des doubles IEEE, zéro étant 1899-12-31 je crois. Dans la réponse acceptée, je trouve que même SELECT DATEDIFF (jour, '2019-01-01', '2019-04-09') / 100; renvoie zéro, car DATEDIIF renvoie un entier et la division entière prend le dessus
Notez que
DateDiff
renvoie le nombre de frontières franchies, par exemple le nombre de jours du2000-01-01 00:15:00
au2000-01-01 23:45:00
est0
, mais de2000-01-01 23:59:30
à2000-01-02 00:00:42
est1
. Afin d'obtenir des résultats cohérents avec le code d'accès, vous devrez peut-être utiliser une partie de date plus petite, par exempleseconde
plutôt quejour
, avec un ajustement correspondant dans l'arithmétique, par ex. en divisant par86400
. Notez que le type de retour estint
ce qui limite la plage.@Cato mon point ne change pas.
2019-01-21 / 2
n'a aucun sens. Les dates ne sont pas des nombres (et sachez que lorsque les gens les traitent comme des nombres, ils ont des problèmes).@larnu date1 - date2 pourrait signifier quelque chose, en .net, c'est une période, mais le concept semble manquer dans SQL
@Cato en fait, il a été supprimé (n'était pas inclus) avec
datetime2
et les autres nouveaux types de données;datetime
le prend toujours en charge (mais encore une fois, cela ne veut pas dire que cela a du sens).Je suis d'accord avec @Lamu sur le contexte. La façon dont je vois ce scénario, la demande est d'obtenir une différence entre les dates, puis de diviser par 100. Donc ... s'il y a une différence de 2 jours, les résultats sont 0,02? Que signifie 0,02? Je ne vois pas comment cela se traduit par quelque chose de significatif. Cela étant dit, l'accès MS permet la soustraction de deux dates comme OP présenté. Diviser par 100 est la curiosité. À cette fin, je ne pense pas que la réponse choisie produise le même résultat que MS Access car elle fonctionne comme Int. J'obtiens un zéro lorsque je l'essaye au lieu d'une valeur décimale.
@ level3looper - cela pourrait faire partie d'un calcul plus large, par exemple de simples paiements d'intérêts quotidiens - s'il s'agissait d'un intérêt de 1% par jour par exemple