2016-10-07 4 views
5

計算された列をSQL Serverテーブルに追加しようとすると、DATE型の列を直接VARCHARにキャストすることが非決定的であると判断されました。しかし、もし私が日付の個々の部分を取り出して個別にキャストすると、すべてが問題ありません。 DATEからVARCHARへの直接キャストが非決定論的である理由について、合理的な説明をすることはできません。誰か説明がありますか?DATEからVARCHARへのキャストが非決定的なのはなぜですか?

Ex。日付の

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 

おかげで、

イアン

+0

3桁の2番目のパラメータを 'convert()'に追加しても、それでもまだ確定していませんか?私はそれがBOLで明確に説明されたと思った。 – ajeh

答えて

6

文字列(varchar型)の表現は、あなたの「ロケール」の設定(英国では例えば日付は、多くの場合、米国では異なる方法で表現されている)に依存します。

上記の例では、最初のCAST()は明示的にvarcharの形式を指定しますが、2番目の形式では、データベースがそのロケール設定を調べてvarchar結果の形式を決定します。

変換がCAST()関数の外部のものに依存するという単純な事実により、非決定論的になります。

つまり、あるロケール設定でCAST()を実行し、ロケールを変更してからSAME CAST()を再度実行すると、別の結果が得られます。これは、非決定的な振る舞いの定義です。

+0

もちろん、あなたは正しいです。私はそれを考慮すべきだった。これにより、CASTの代わりにCONVERTを使用することをお勧めします。このソリューションは、日付の各部分を別々にキャストするよりも短時間で動作します。 - これは問題なく動作します。 テーブルを変更するdbo.junk_CCtest \t Checksum3を(hashbytes( 'sha2_256'、EmployerId + '/' + cast(PatientId as varchar(10))+ convert(varchar(8)、EffDate、112)))として保存します。 –

関連する問題