web-dev-qa-db-fra.com

Combinaison (concaténation) de la date et de l'heure dans un datetime

À l'aide de SQL Server 2008, cette requête fonctionne parfaitement:

select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field

Me donne deux colonnes comme ceci:

2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
2013-01-25  18:53:00.0000000
    .
    .
    .

J'essaie de les combiner en un seul horodatage en utilisant le signe plus, comme ceci:

select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field

J'ai consulté une dizaine de sites Web, y compris des réponses sur ce site (comme celui-ci ), et ils semblent tous d'accord pour dire que le signe plus devrait fonctionner, mais je reçois l'erreur:

Msg 8117, niveau 16, état 1, ligne 1
La date du type de données d'opérande n'est pas valide pour l'opérateur add.

Tous les champs sont non nuls et non nuls. J'ai également essayé la fonction CONVERT et essayé de convertir ces résultats en varchars, même problème. Cela ne peut pas être aussi difficile que je le fais.

Quelqu'un peut-il me dire pourquoi cela ne fonctionne pas? Merci pour toute aide.

21
Stanton

En supposant que les types de données sous-jacents sont date/heure/date/heure, etc.

SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112) 
  + ' ' + CONVERT(CHAR(8), CollectionTime, 108))
  FROM dbo.whatever;

S'ils ne le sont pas,WHY NOT, et pour obtenir une réponse significative, vous devrez nous indiquer leur type et le format dans lequel les données sont stockées. Ou corrigez simplement la table.

33
Aaron Bertrand

Lancez-le à datetime à la place:

select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field

Cela fonctionne sur SQL Server 2008 R2.

Si, pour une raison quelconque, vous voulez vous assurer que la première partie ne comporte pas de composant heure, commencez par transtyper le champ à la date, puis à nouveau sur datetime.

9
Amy

Une solution plus simple (testée sur SQL Server 2014 SP1 CU6) 

Code: 

DECLARE @Date date = SYSDATETIME();

DECLARE @Time time(0) = SYSDATETIME();

SELECT CAST(CONCAT(@Date, ' ', @Time) AS datetime2(0));

Cela fonctionnerait également avec une table avec une date et un champ d'heure spécifiques. J'utilise fréquemment cette méthode, car nous disposons de données sur les fournisseurs qui utilisent la date et l'heure dans deux champs distincts.

6
texasrebelaggie

La solution simple

SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME)
FROM field
5
Park Keeper
DECLARE @ADate Date, @ATime Time, @ADateTime Datetime

SELECT @ADate = '2010-02-20', @ATime = '18:53:00.0000000'

SET @ADateTime = CAST   (
    CONVERT(Varchar(10), @ADate, 112) + ' ' +   
    CONVERT(Varchar(8), @ATime) AS DateTime)

SELECT @ADateTime [A Nice datetime :)]

Cela vous rendra un résultat valide.

1
Elken
drop table test

create table test(
    CollectionDate date NULL,
    CollectionTime  [time](0) NULL,
    CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate))
-- if CollectionDate is datetime no need to convert it above
)

insert test (CollectionDate, CollectionTime)
values ('2013-12-10', '22:51:19.227'),
       ('2013-12-10', null),
       (null, '22:51:19.227')

select * from test

CollectionDate  CollectionTime  CollectionDateTime
2013-12-10      22:51:19        2013-12-10 22:51:19.000
2013-12-10      NULL            2013-12-10 00:00:00.000
NULL            22:51:19        NULL
0
dinok

Cela fonctionne dans SQL 2008 et 2012 pour produire datetime2:

declare @date date = current_timestamp;
declare @time time = current_timestamp;

select 
@date as date
,@time as time
,cast(@date as datetime) + cast(@time as datetime) as datetime
,cast(@time as datetime2) as timeAsDateTime2
,dateadd(dayofyear,datepart(dayofyear,@date) - 1,dateadd(year,datepart(year,@date) - 1900,cast(@time as datetime2))) as datetime2;
0
same