Te doy la bienvenida a proyecto online, en este sitio vas a hallar la respuesta a lo que necesitas.
Solución:
La respuesta (anteriormente) aceptada esfue incorrecto ya que esfue una prueba mala y engañosa. Las dos consultas que se comparan no hacen lo mismo debido a un simple error tipográfico que hace que no sean una comparación de manzanas con manzanas. La prueba en la respuesta aceptada está injustamente sesgada a favor de la CAST
operación. El problema es que el CONVERT
la operación se está haciendo con convert(date, GETDATE()+num,20)
– un valor para convertir que cambia por fila – mientras que el CAST
La operación se realiza con un simple cast(GETDATE() as date)
– un valor para convertir que es consistente en todas las filas y se reemplaza en el plan de ejecución como una constante. Y de hecho, mirar el plan de ejecución XML incluso muestra que la operación real realizada es CONVERT(date,getdate(),0)
!!
En la medida en que muestran mis pruebas (después de igualarlas mediante el uso de cast(GETDATE()+num as date)
), los tiempos varían, siendo en su mayoría los mismos (lo que tiene sentido si ambos se reducen a ser CONVERT
de todos modos) o el CONVERT
victorioso:
SET STATISTICS IO, TIME ON;
;with t as (
select convert(date, GETDATE(),20) as fecha , 0 as num
union all
select convert(date, GETDATE()+num,20) as fecha, num+1 from t where num<1000000)
select max(fecha)
from t
option (maxrecursion 0);
SET STATISTICS IO, TIME OFF;
-- 4754-07-23
--Table 'Worktable'. Scan count 2, logical reads 6000008, physical reads 0, read-ahead reads 0
-- SQL Server Execution Times:
-- CPU time = 9031 ms, elapsed time = 9377 ms.
-- VS
SET STATISTICS IO, TIME ON;
;with t as (
select cast(GETDATE() as date) as fecha , 0 as num
union all
select cast(GETDATE() as date) as fecha, num+1 from t where num<1000000)
select max(fecha)
from t
option (maxrecursion 0);
SET STATISTICS IO, TIME OFF;
--2016-08-26
--Table 'Worktable'. Scan count 2, logical reads 6000008, physical reads 0, read-ahead reads 0
-- SQL Server Execution Times:
-- CPU time = 8969 ms, elapsed time = 9302 ms.
SET STATISTICS IO, TIME ON;
;with t as (
select cast(GETDATE() as date) as fecha , 0 as num
union all
select cast(GETDATE()+num as date) as fecha, num+1 from t where num<1000000)
select max(fecha)
from t
option (maxrecursion 0);
SET STATISTICS IO, TIME OFF;
-- 4754-07-23
--Table 'Worktable'. Scan count 2, logical reads 6000008, physical reads 0, read-ahead reads 0
-- SQL Server Execution Times:
-- CPU time = 9438 ms, elapsed time = 9878 ms.
La principal diferencia entre CAST y CONVERT es que CONVERT
permite especificar el "estilo". El "estilo" no solo permite adaptar el producción al convertir un nostring a un string, pero también permite especificar el aporte formato al convertir un string a un nostring:
SELECT CONVERT(DATE, '5/10/2016', 101); -- 101 = mm/dd/yyyy
-- 2016-05-10
SELECT CONVERT(DATE, '5/10/2016', 103); -- 103 = dd/mm/yyyy
-- 2016-10-05
Ahora compara eso funcionalmente con CAST
:
SELECT CAST('13/5/2016' AS DATE);
-- Msg 241, Level 16, State 1, Line 71
-- Conversion failed when converting date and/or time from character string.
SELECT CONVERT(DATE, '13/5/2016', 101); -- 101 = mm/dd/yyyy
-- Msg 241, Level 16, State 1, Line 76
-- Conversion failed when converting date and/or time from character string.
SELECT CONVERT(DATE, '13/5/2016', 103); -- 103 = dd/mm/yyyy
-- 2016-05-13
Una cosa adicional para mencionar CAST
: debido a que no tiene el parámetro "estilo", el formato de la fecha string pasado se supone que es el de la cultura actual (una propiedad de sesión). La cultura actual se denota por el @@LANGID
y @@LANGUAGE
variables del sistema. Esto significa que el CAST
La declaración que falló en la prueba directamente anterior podría tener éxito para una cultura / idioma diferente. Las siguientes pruebas muestran este comportamiento y cómo esa misma fecha string funciona con CAST
cuando el idioma actual es "francés" (y funcionaría con varios otros, según los valores de la dateformat
columna en sys.syslanguages
):
IF (@@LANGID <> 0) -- us_english
BEGIN
PRINT 'Changing LANGUAGE to English...';
SET LANGUAGE ENGLISH;
SELECT @@LANGUAGE AS [CurrentLanguage], @@LANGID AS [LangID];
END;
SELECT @@LANGUAGE, CAST('13/5/2016' AS DATE) AS [Test 1];
-- Msg 241, Level 16, State 1, Line 71
-- Conversion failed when converting date and/or time from character string.
GO
SELECT @@LANGUAGE, CONVERT(DATE, '13/5/2016', 103) AS [Test 2]; -- 103 = dd/mm/yyyy
-- us_english 2016-05-13
GO
IF (@@LANGID <> 2) -- Français
BEGIN
PRINT 'Changing LANGUAGE to French...';
SET LANGUAGE FRENCH;
SELECT @@LANGUAGE AS [CurrentLanguage], @@LANGID AS [LangID];
END;
SELECT @@LANGUAGE, CAST('13/5/2016' AS DATE) AS [Test 3];
-- 2016-05-13
GO
SELECT @@LANGUAGE, CONVERT(DATE, '13/5/2016', 103) AS [Test 4]; -- 103 = dd/mm/yyyy
-- Français 2016-05-13
GO
-- Reset current language, if necessary.
IF (@@LANGID <> @@DEFAULT_LANGID)
BEGIN
DECLARE @Language sysname;
SELECT @Language = sl.[alias]
FROM sys.syslanguages sl
WHERE sl.[langid] = @@DEFAULT_LANGID;
PRINT N'Changing LANGUAGE back to default: ' + @Language + N'...';
SET LANGUAGE @Language;
SELECT @@LANGUAGE AS [CurrentLanguage], @@LANGID AS [LangID];
END;
No tengo conocimiento de ninguna diferencia de "rendimiento" entre los dos. Aparentemente, "CONVERT" es específico de Sql Server, mientras que CAST es estándar ANSI. Creo que CONVERT te ofrece más opciones. Puede ver otros pros / contras aquí (http://searchsqlserver.techtarget.com/tip/The-difference-between-CONVERT-and-CAST-in-SQL-Server)
Cotizaciones directas del enlace ...
Debido a que SQL Server proporciona ambas funciones, puede haber cierta confusión sobre cuál es mejor utilizar y bajo qué circunstancias.
CONVERT es específico de SQL Server y permite una mayor flexibilidad al convertir entre valores de fecha y hora, números fraccionarios y significantes monetarios.
CAST es la más estándar ANSI de las dos funciones, lo que significa que si bien es más portátil (es decir, una función que usa CAST se puede usar en otras aplicaciones de base de datos más o menos tal cual), también es menos poderosa.
Probé esta tonta comparación. Editado, hubo un error tipográfico que mencionó @srutzky. Los resultados están cerca.
;with t as (
select convert(date, GETDATE(),20) as fecha , 0 as num
union all
select convert(date, GETDATE()+num,20) as fecha, num+1 from t where num<1000000)
select max(fecha)
from t
option (maxrecursion 0);
-- VS
;with t as (
select cast(GETDATE() as date) as fecha , 0 as num
union all
select cast(GETDATE()+num as date) as fecha, num+1 from t where num<1000000)
select max(fecha)
from t
option (maxrecursion 0);
Los resultados fueron muy consistentes:
- Convertir: 8,6 segundos
- Reparto: 8,7 segundos