2
votes

La clause Where échoue lorsqu'elle est utilisée avec une fonction 'convert'

Je convertis un champ varchar représentant une date en datetime, et je l'utilise avec la clause "where - between" .

J'obtiens:

La conversion a échoué lors de la conversion de la date et / ou de l'heure du caractère chaîne

Ma clause where est:

select
screen_date
from d8003
where convert(datetime, screen_date, 120) between '6/1/2018' and '12/31/2018'

Comment résoudre ce problème?


0 commentaires

4 Réponses :


2
votes

Essayez d'utiliser la syntaxe suivante (utilisez le format de date AAAAMMJJ au lieu de MM / JJ / AAAA):

select
screen_date
from d8003
where convert(datetime, screen_date, 120) between '20180601' and '20181231'

Si vous obtenez toujours la même erreur, vérifiez que vous utilisez le bon format de date code:


5 commentaires

@deGuza quel est le format de date stocké dans la colonne screen_date


La colonne screen_date est stockée sous le nom "varchar"


@deGuza je sais mais quel est le format de la date. Les valeurs sont-elles stockées comme '31 / 12/1980 'ou '12 / 31/1989' ou autre?


@deGuza essayez d'utiliser 101 ou 102


* Le Screen_Date apparaît comme "30/05/2018". * L'utilisation de 101 ou 102 ne fonctionnait pas non plus.



0
votes

Avant 2005, les capacités de gestion des erreurs étaient très limitées. Pour SQL 2005+, cela devrait fonctionner

select 
    try_convert(datetime, screen_date, 120) mytryconvert
    ,screen_date
from d8003
where try_convert(datetime, screen_date, 120) is null

Cela renverra vos mauvaises données dans SQL 2012+ try_convert, renverra un null sur les chaînes non convertibles.

declare 
     @date_value varchar(50)
    ,@tmp datetime;
declare x cursor local fast_forward 
for
select screen_date from d8003

open x;
fetch next from x into @date_value;
while @@fetch_status = 0
    begin
        begin try
            set @tmp = convert(datetime,@date_value, 120)
        end try
        begin catch
            select 'This one is bad! Please fix me!! (' + rtrim(@date_value) + ')' bad_values;
        end catch
        fetch next from x into @date_value;
    end
close x;
deallocate x;
GO

Vous pouvez corriger les données manuellement ou en ligne avec la manipulation de chaînes.


3 commentaires

Malheureusement, la fonction try_convert ne semble pas être disponible sur ma version de SQL


quelle version de SQL Server utilisez-vous? J'ai ajouté un moyen d'obtenir les mêmes données qui devraient revenir à SQL 2005. SQL 2000 n'avait pas une bonne gestion des erreurs.


À partir de la version 2005, il y a un XQuery -hack, simulant TRY_CAST () . Vérifiez cette réponse ou une approche encore plus courte ici . Il autorisera les transtypages intégrés sans qu'une erreur ne soit générée, renvoyant simplement NULL à la place. Mais il n'y a pas d'équivalent pour TRY_CONVERT et son paramètre de style ...



1
votes

Utilisez TRY_CAST si vous ne savez pas si la valeur peut réellement être convertie.

Mais sachez que le fait que vous recevez cette erreur indique probablement un problème avec certains enregistrements de votre colonne. N'utilisez TRY_CAST que si vous vous souciez uniquement d'obtenir les enregistrements où la colonne varchar peut réellement être convertie en datetime.

SELECT
    [screen_date]
FROM
    [d8003]
WHERE
    TRY_CAST([screen_date] AS DATETIME) BETWEEN '6/1/2018' AND '12/31/2018'


0 commentaires

0
votes

Merci pour toutes les suggestions et l'assistance que vous nous avez offertes. Je suis heureux de vous dire que j'ai trouvé la solution. Voici mon code:

où try_cast (screen_date as smalldatetime) entre '2018-06-01' et '2018-12-31'

C'est une suggestion d'un collègue qui a de nombreuses années d'expérience. (Je viens de commencer à coder en SQL ....)

C'était une suggestion de l'un d'entre vous plus tôt, je ne sais pas pourquoi cela n'a pas fonctionné à l'époque.

Deguza


2 commentaires

Salut deGuza, je suis heureux que vous ayez trouvé une solution! Merci de bien vouloir clore cette question en acceptant la réponse que vous aimez le plus et d’utiliser votre droit de vote sur toute contribution qui vous semble en valoir la peine. Bon codage!


Un conseil: il était préférable d'utiliser '20181231' au lieu de '2018-12-31' . Le format séparé par des tirets dépend - dans certaines situations - de la culture. Une valeur comme 2018-02-01 pourrait se révéler 2 janvier sur un autre système (alors que la valeur ci-dessus lèverait une exception).