为什么从DATE到VARCHAR的演员表是非确定性的?

时间:2016-10-07 16:22:02

标签: sql-server tsql

在尝试将计算列添加到SQL Server表时,我发现将DATE类型的列直接转换为VARCHAR被认为是不确定的。但是,如果我拉出日期的各个部分并单独投射,那么一切都很好。我不能想到一个合理的解释为什么直接从DATE到VARCHAR的演员阵容是非确定性的。有人有解释吗?

实施例

create table [dbo].[junk_CCtest]
(
    PatientId bigint identity not null,
    EmployerId varchar(6) default 'F*Corp',
    EffDate date default getdate()
)
go
-- This works fine.
alter table dbo.junk_CCtest
    add Checksum1 as (hashbytes('sha2_256', EmployerId + '/' + cast(PatientId as varchar(10)) + cast(year(EffDate) as varchar(4)) + cast(month(EffDate) as varchar(2))  + cast(day(EffDate) as varchar(2)))) persisted;
go
-- This results in: "Computed column 'Checksum3' in table 'junk_CCtest' cannot be persisted because the column is non-deterministic."
alter table dbo.junk_CCtest
    add Checksum3 as (hashbytes('sha2_256', EmployerId + '/' + cast(PatientId as varchar(10)) + cast(EffDate as varchar(10)))) persisted;
go

谢谢,

伊恩

1 个答案:

答案 0 :(得分:6)

日期的字符串(varchar)表示取决于您的"区域设置"设置(例如,英国的日期通常与美国不同)。

在上面的示例中,您的第一个CAST()显式指定了varchar的格式,但第二个强制数据库检查其语言环境设置以确定如何格式化varchar结果。

转换依赖于CAST()函数外部的事实这一简单事实使其不确定。

换句话说,您使用一个区域设置运行CAST(),更改区域设置,然后再次运行 SAME CAST(),您将得到不同的结果。这是非确定性行为的定义。