Die (früher) akzeptierte Antwort istwar falsch wie es istwar ein schlechter und irreführender Test. Die beiden verglichenen Abfragen machen aufgrund eines einfachen Tippfehlers, der dazu führt, dass sie kein Apfel-zu-Apfel-Vergleich sind, nicht dasselbe. Der Test in der akzeptierten Antwort ist zu Unrecht zugunsten der CAST
Operation voreingenommen . Das Problem ist, dass die CONVERT
Operation ausgeführt wird convert(date, GETDATE()+num,20)
- ein Wert zum Konvertieren, der sich pro Zeile ändert -, während die CAST
Operation mit einem einfachen cast(GETDATE() as date)
Wert ausgeführt wird - ein Wert zum Konvertieren, der über alle Zeilen hinweg konsistent ist und im Ausführungsplan ersetzt wird als Konstante. Wenn Sie sich den XML-Ausführungsplan ansehen, wird sogar die tatsächlich ausgeführte Operation als CONVERT(date,getdate(),0)
!! angezeigt.
Soweit meine Tests zeigen (nachdem sie durch Verwendung gleich gemacht wurden cast(GETDATE()+num as date)
), sind die Zeiten, in denen sie variieren, größtenteils gleich (was sinnvoll ist, wenn beide CONVERT
sowieso reduziert sind ) oder der CONVERT
Gewinn:
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.
Der Hauptunterschied zwischen CAST und CONVERT besteht darin, CONVERT
dass der "Stil" angegeben werden kann. Der "Stil" ermöglicht nicht nur das Anpassen der Ausgabe beim Konvertieren eines Nicht-Strings in einen String, sondern auch das Festlegen des Eingabeformats beim Konvertieren eines Strings in einen Nicht-String:
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
Vergleichen Sie das nun funktional mit 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
Eine weitere Sache, die Sie erwähnen sollten CAST
: Da der Parameter "style" nicht vorhanden ist, wird angenommen, dass das Format der übergebenen Datumszeichenfolge das der aktuellen Kultur ist (eine Sitzungseigenschaft). Die aktuelle Kultur wird durch die Systemvariablen @@LANGID
und @@LANGUAGE
bezeichnet. Dies bedeutet, dass die CAST
Aussage, die im Test direkt oben fehlgeschlagen ist, für eine andere Kultur / Sprache erfolgreich sein kann. Die folgenden Tests zeigen dieses Verhalten und wie dieselbe Datumszeichenfolge funktioniert, CAST
wenn die aktuelle Sprache "Französisch" ist (und mit mehreren anderen funktionieren würde, basierend auf den Werten in der dateformat
Spalte in 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;