2010-02-26 2 views
0

J'ai une fonction SQL Server qui convertit un paramètre de durée de jour nvarchar en valeur datetime.Transformation du paramètre de durée du jour nvarchar en date-heure

Le jour format de durée est > jours <> heures <:.> Minutes <, par exemple 1.2: 00 pour un jour et deux heures.

Le format du paramètre de durée du jour ne peut pas être modifié et nous pouvons être sûrs que toutes les données sont correctement formatées et présentes.

En donnant à la fonction une heure de début et le réglage de la durée du jour, elle doit retourner l'heure de fin.

Par exemple: 2010-01-02 13:30 ==> 2010-01-03 02h00

J'utilise une combinaison de charindex, et convertir des méthodes sous-chaîne pour calculer la valeur, qui est plutôt lent et akward. Existe-t-il un autre moyen de convertir directement ce paramètre de durée de jour en valeur de date/heure?

Répondre

2

Pas d'après ce que je peux voir. Je finirais avec un peu similaire de SQL comme vous, en utilisant charindex etc Malheureusement, c'est au format de la durée du jour est stocké. Je sais que vous ne pouvez pas le changer, mais si c'était dans un format différent, il serait être beaucoup plus facile - la façon dont je le ferais habituellement par exemple, est de rationaliser la durée jusqu'à une unité de base comme les minutes. Au lieu de stocker 1.2: 00 pendant 1 jour et 2 heures, ce serait (1 * 24 * 60) + (2 * 60) = 1560. Cela pourrait alors être utilisé dans un simple DATEADD à la date d'origine (partie de date seulement).

Avec le format que vous avez, toutes les approches que je peux penser impliquer l'utilisation CHARINDEX etc.

+0

Ouais ... Je sais que, malheureusement, mais le format est en quelque sorte l'héritage et je ne peux pas le changer car il est utilisé dans d'autres systèmes. – Drejc

+0

@Drejc - Je ne pense pas qu'il y ait un autre moyen d'être honnête. Est-ce définitivement la cause de la lenteur des performances? L'autre chose que je suggère est de ne pas faire le calcul dans SQL Server, mais retourner les deux champs tels quels et laisser le code appelant le faire qui fonctionnera mieux à la manipulation de la chaîne – AdaTheDev

+0

Ceci est réellement fait de la façon dont vous décrivez, sauf pour une situation, où le calcul doit être effectué du côté SQL. Il ne provoque pas de réponses lentes ou des problèmes similaires, mais c'est juste une solution laide. – Drejc

1

Une alternative serait de construire une chaîne avec le calcul. Ensuite, vous pouvez exécuter le SQL généré avec sp_executesql, en spécifiant @enddate comme paramètre de sortie:

declare @startdate datetime 
declare @duration varchar(10) 
declare @enddate datetime 

set @startdate = '2010-01-02 13:30' 
set @duration = '0.12:30' 

declare @sql nvarchar(max) 
set @sql = 'set @enddate = dateadd(mi,24*60*' + 
    replace(replace(@duration,'.','+60*'),':','+') + ', @startdate)' 
exec sp_executesql @sql, 
    N'@startdate datetime, @enddate datetime out', 
    @startdate, @enddate out 

Cela crée une chaîne contenant set @enddate = dateadd(mi,24*60*0+60*12+30, @startdate) puis exécute.

Je doute que ce soit plus rapide que la façon charindex régulière:

declare @pos_dot int 
declare @day int 
declare @hour int 
declare @minute int 

select 
    @pos_dot = charindex('.',@duration), 
    @day = cast(left(@duration, @pos_dot-1) as int), 
    @hour = cast(left(right(@duration, 5), 2) as int), 
    @minute = cast(right(@duration, 2) as int), 
    @enddate = dateadd(mi, 24*60*@day + 60*@hour + @minute, @startdate) 
+0

Huh ... c'est certainement un moyen de le faire, mais il est très illisible et la prochaine personne qui regarde cela dira juste FTW;) – Drejc

+1

Vous avez demandé une solution sans charindex tho;) – Andomar

+0

+1, génial! ce spectacle montre pourquoi CHARINDEX est important !!vous pourriez vous rendre la version de charindex plus simple avec un GAUCHE() pour les jours et un DROIT() pour les minutes –