Câu trả lời (trước đây) được chấp nhận Làkhông chính xác vì nó Làlà một bài kiểm tra tồi và sai lệch. Hai truy vấn được so sánh không làm điều tương tự do một lỗi đánh máy đơn giản khiến chúng không phải là một so sánh táo với táo. Các thử nghiệm trong câu trả lời được chấp nhận là thiên vị không công bằng ủng hộ CAST
hoạt động. Vấn đề là CONVERT
hoạt động đang được thực hiện với convert(date, GETDATE()+num,20)
- một giá trị để chuyển đổi thay đổi trên mỗi hàng - trong khi CAST
thao tác được thực hiện đơn giản cast(GETDATE() as date)
- một giá trị để chuyển đổi phù hợp trên tất cả các hàng và được thay thế trong kế hoạch thực hiện như một hằng số. Và trên thực tế, nhìn vào kế hoạch thực hiện XML thậm chí còn cho thấy hoạt động thực tế được thực hiện như hiện tại CONVERT(date,getdate(),0)
!!
Trong chừng mực mà thử nghiệm của tôi cho thấy (sau khi làm cho chúng bằng nhau thông qua việc sử dụng cast(GETDATE()+num as date)
), thời gian thay đổi với chúng hầu như giống nhau (điều này có ý nghĩa nếu cả hai đều giảm xuống thành CONVERT
dù sao) hoặc CONVERT
chiến thắng:
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.
Sự khác biệt chính giữa CAST và CONVERT là CONVERT
cho phép "kiểu" được chỉ định. "Kiểu" không chỉ cho phép điều chỉnh đầu ra khi chuyển đổi một chuỗi không thành chuỗi, mà còn cho phép chỉ định định dạng đầu vào khi chuyển đổi một chuỗi thành một chuỗi không:
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
Bây giờ so sánh chức năng đó với 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
Một điều nữa cần đề cập đến CAST
: bởi vì nó không có tham số "kiểu", định dạng của chuỗi ngày được truyền vào được coi là của văn hóa hiện tại (thuộc tính phiên). Văn hóa hiện tại được biểu thị bởi các biến @@LANGID
và @@LANGUAGE
hệ thống. Điều này có nghĩa là CAST
tuyên bố thất bại trong bài kiểm tra trực tiếp ở trên có thể thành công cho một nền văn hóa / ngôn ngữ khác. Các thử nghiệm sau đây cho thấy hành vi này và cách chuỗi ngày tương tự hoạt động CAST
khi ngôn ngữ hiện tại là "tiếng Pháp" (và sẽ hoạt động với một số ngôn ngữ khác, dựa trên các giá trị trong dateformat
cột trong 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;