restar operaciones minutos insertar horas fechas fecha example ejemplos ejemplo con sql sql-server sql-server-2005 tsql datetime

operaciones - Fecha dinámica de SQL cuando se usa DateDiff



operaciones con fechas sql (6)

¿Hay una manera de pasar el parámetro DatePart de DateDiff como una variable? ¿Para que pueda escribir código que sea similar a esto?

DECLARE @datePart VARCHAR(2) DECLARE @dateParameter INT SELECT @datePart = ''dd'' SELECT @dateParameter = 28 SELECT * FROM MyTable WHERE DATEDIFF(@datePart, MyTable.MyDate, GETDATE()) < @dateParameter

Las únicas maneras en que puedo pensar en hacerlo es con una sentencia CASE que verifique el valor del parámetro o construyendo el SQL como una cadena y ejecutándolo en un EXEC.

¿Alguien tiene alguna sugerencia "mejor"? La plataforma es MS SQL Server 2005.


Creé una función de valores escalares para hacer esto. Se basa en las soluciones mencionadas anteriormente pero es más fácil de implementar en su código.

CREATE FUNCTION [dbo].[dynamic_dateadd] ( @unit varchar(5), @number int, @dt datetime ) RETURNS datetime AS BEGIN declare @result datetime if (@unit=''M'') BEGIN SET @result=(select DATEADD(M,@number,@dt)) END if (@unit=''WW'') BEGIN SET @result=(select DATEADD(WW,@number,@dt)) END if (@unit=''D'') BEGIN SET @result=(select DATEADD(D,@number,@dt)) END if (@unit=''H'') BEGIN SET @result=(select DATEADD(HH,@number,@dt)) END return(@result) END

En una consulta puedes usar esta función así:

select startdate, validity_unit, validity_number, dbo.dynamic_dateadd(valididy_unit,validity_number,startdate) as enddate from SALES_subscription


De acuerdo con la entrada de BOL en DATEDIFF (sección de argumentos ) para SQL Server 2005,

Estas partes de fecha y abreviaturas no se pueden suministrar como una variable declarada por el usuario.

Por lo tanto, es probable que esté atascado con SQL dinámico o con una sentencia CASE. Pero optaría por una versión CASE en lugar de SQL dinámico.


Definitivamente, el uso de la consulta dinámica como la que se muestra a continuación funciona muy bien, supongo que planea usar solo la abreviatura de @datePart. Recomendaría usar un mínimo de VARCHAR (4) para datepart, esto manejará las abreviaturas como aaaa y mcs. Codificación feliz:

DECLARE @datePart VARCHAR(2) DECLARE @dateParameter INT DECLARE @SQLTemp varchar(MAX) SELECT @datePart = ''dd'' SELECT @dateParameter = 28 set @SQLTemp =''SELECT * FROM MyTable WHERE DATEDIFF(''+@datePart+'', ''+MyTable.MyDate+'', GETDATE()) < ''+@dateParameter exec (@SQLTemp)


Lo único que realmente puede hacer aparte de la declaración de caso o sql dinámica sugerida es hacer siempre la fecha en una DatePart granular y luego realizar una conversión ascendente. Sin embargo, esto no es infalible, obtendrá un desbordamiento en la función si intenta realizar un cambio de fecha a granular en un intervalo demasiado grande, por ejemplo, dateiff (segundo, 0, getdate ()). Pero si solo necesita partes como minutos, debería estar bien (verifique dos veces con los valores de fecha máxima que le interesan).

Así por ejemplo

select datediff(minute, 0, getdate())

Si quiero convertir esto en horas, días, etc., solo puedo dividir el resultado por la cantidad apropiada. No tendrá en cuenta los años bisiestos, etc.


No creo que haya mejores maneras de lo que tu describes. El servidor Sql probablemente compile la consulta DATEDIFF en un conjunto de operaciones que dependen del parámetro datepart. Así que necesitarías un CASO, o consultas dinámicas.


Viejo pero todavía válido por desgracia.

Lo hice de forma correcta y solo quiero compartir el código para que no tenga que hacer todo el trabajo molesto que tenía que hacer. Cubre todas las partes de fecha posibles. Simplemente reemplace el nombre de la función y la función de fecha para implementar para otras funciones de fecha de T-SQL.

Copiar y pegar sección

-- SELECT dbo.fn_DateAddFromStringPart(''year'', 1, GETDATE()) CREATE FUNCTION fn_DateAddFromStringPart ( @Interval VARCHAR(11), @Increment INT, @Date SMALLDATETIME ) RETURNS DATETIME AS BEGIN -- Declare the return variable here DECLARE @NewDate DATETIME -- Add the T-SQL statements to compute the return value here SELECT @NewDate = CASE WHEN @Interval IN (''year'', ''yy'', ''yyyy'') THEN DATEADD(YEAR, @Increment, @Date) WHEN @Interval IN (''quarter'', ''qq'', ''q'') THEN DATEADD(QUARTER, @Increment, @Date) WHEN @Interval IN (''month'', ''mm'', ''m'') THEN DATEADD(MONTH, @Increment, @Date) WHEN @Interval IN (''dayofyear'', ''dy'', '''') THEN DATEADD(DAYOFYEAR, @Increment, @Date) WHEN @Interval IN (''day'', ''dd'', ''d'') THEN DATEADD(DAY, @Increment, @Date) WHEN @Interval IN (''week'', ''wk'', ''ww'') THEN DATEADD(WEEK, @Increment, @Date) WHEN @Interval IN (''weekday'', ''dw'', ''w'') THEN DATEADD(WEEKDAY, @Increment, @Date) WHEN @Interval IN (''hour'', ''hh'') THEN DATEADD(HOUR, @Increment, @Date) WHEN @Interval IN (''minute'', ''mi'', ''n'') THEN DATEADD(MINUTE, @Increment, @Date) WHEN @Interval IN (''second'', ''ss'', ''s'') THEN DATEADD(SECOND, @Increment, @Date) WHEN @Interval IN (''millisecond'', ''ms'') THEN DATEADD(MILLISECOND, @Increment, @Date) WHEN @Interval IN (''microsecond'', ''mcs'') THEN DATEADD(MICROSECOND, @Increment, @Date) WHEN @Interval IN (''nanosecond'', ''ns'') THEN DATEADD(NANOSECOND, @Increment, @Date) END -- Return the result of the function RETURN @NewDate END GO