Combinaison (concaténation) de la date et de l'heure dans une datetime
en utilisant SQL Server 2008, cette requête fonctionne très bien:
select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field
Donne-moi 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 une seule datetime en utilisant le signe plus, comme ceci:
select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field
j'ai regardé environ dix sites web, y compris les réponses sur ce site (comme celui-ci), et ils semblent tous d'accord que le signe devrait fonctionner, mais j'obtiens l'erreur:
Msg 8117, Niveau 16, État 1, Ligne 1
La date du type de données Operand n'est pas valide pour l'opérateur add.
Tous les champs sont non nulles et non nulles. J'ai aussi essayé la fonction CONVERT et essayé de lancer ces résultats comme varchars, même problème. Ça ne doit pas être aussi dur que je le fais.
Quelqu'un peut-il me dire pourquoi ça ne marche pas? Merci pour toute aide.
9 réponses
en supposant que les types de données sous-jacents sont date/heure/datetime, etc.
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112)
+ ' ' + CONVERT(CHAR(8), CollectionTime, 108))
FROM dbo.whatever;
Si ils ne le sont pas, POURQUOI PAS, et pour obtenir une réponse significative, vous aurez besoin de nous dire quels types ils sont et dans quel format les données sont stockées. Ou tout simplement fixer le tableau.
Cast datetime
au lieu de:
select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field
cela fonctionne sur SQL Server 2008 R2.
si, pour une raison quelconque, vous vouliez vous assurer que la première partie n'a pas de composante temps, jetez d'abord le champ à ce jour, puis revenez à datetime
.
une solution plus facile (testé 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 aussi avec un tableau avec une date spécifique et un champ temporel spécifique. J'utilise souvent cette méthode étant donné que nous avons des données sur les fournisseurs qui utilisent la date et l'heure dans deux champs distincts.
la solution simple
SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME)
FROM field
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.
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
cela fonctionne en 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;
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), date, 112) + ' ' + CONVERT(CHAR(8), time, 108))
FROM tablename