pmd*_*dci 7 sql-server t-sql type-conversion azure-sql-database cast
考虑以下两种将日期时间 varchar 字符串转换为日期字段的方法:
SELECT convert(date, '2012-12-21 21:12:00', 20) -- Only date is needed
SELECT cast('2012-12-21 21:12:00' as date) -- Only date is needed
Run Code Online (Sandbox Code Playgroud)
两者都返回我期望的内容:不包括时间的日期,作为日期数据类型。
我的问题是:这两种方式有什么利弊吗?
Sol*_*zky 11
(以前)接受的答案 是是不正确的 是是一个糟糕的和误导性的测试。由于一个简单的错字导致它们不是苹果对苹果的比较,因此被比较的两个查询不会做同样的事情。接受答案中的测试不公平地偏向于CAST操作。问题是CONVERT操作正在使用convert(date, GETDATE()+num,20)- 一个值来转换每行的变化 - 而CAST操作正在使用一个简单的cast(GETDATE() as date)- 一个值来完成,该值在所有行中一致并在执行计划中被替换作为常数。事实上,查看 XML 执行计划甚至显示实际执行的操作是CONVERT(date,getdate(),0)!!
就我的测试显示(通过 using 使它们相等之后cast(GETDATE()+num as date)),时间因它们几乎相同(如果它们都被减少到CONVERT无论如何是有意义的)或CONVERT获胜而变化:
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.
Run Code Online (Sandbox Code Playgroud)
之间的主要区别CAST和CONVERT是CONVERT允许的“风格”来指定。“样式”不仅允许在将非字符串转换为字符串时定制输出,还允许在将字符串转换为非字符串时指定输入格式:
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
Run Code Online (Sandbox Code Playgroud)
现在将其与功能进行比较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
Run Code Online (Sandbox Code Playgroud)
还要提及的另一件事是CAST:因为它没有“样式”参数,所以传入的日期字符串的格式被假定为当前文化(会话属性)的格式。当前文化由系统变量@@LANGID和@@LANGUAGE系统变量表示。这意味着CAST直接在上面的测试中失败的语句对于不同的文化/语言可能会成功。以下测试显示了这种行为以及CAST当当前语言为“法语”时相同的日期字符串如何工作(并且可以与其他几种语言一起使用,基于 中dateformat列中的值sys.syslanguages):
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23038 次 |
| 最近记录: |