計算フィールドにインデックスを作成する:文字列またはバイナリデータは切り捨てられます


8

Foo次のフィールドを持つテーブルがあります。

ID bigint not null identity(1,1),
SerializedValue nvarchar(max),
LongValue as TRY_CAST(SerializedValue as bigint)

次に、LongValueにインデックスを作成して、数値を表すシリアル化された値を簡単に検索できるようにします。

create nonclustered index IX_Foo on Foo(LongValue);

私に次のエラーを吐き出します:

文字列型やバイナリは省略されます。

はい、SerializedValueに既存のデータがあります。しかし、計算されたフィールドにインデックスを作成することで、何が切り捨てられるのでしょうか。

回答:


8

エラーの原因は、インデックスの作成ではありません。このエラーはTRY_CAST、計算された列の値がインデックスの作成時に評価されるときに発生します。

これを実行すると:

SELECT TRY_CAST(REPLICATE(CONVERT(nvarchar(MAX), N'a'), 4001) AS bigint)

同じエラーが発生します。

ドキュメントは(強調鉱山)言います:

キャストが成功した場合、TRY_CASTは指定されたdata_typeとして値を返します。エラーが発生した場合は、nullが返されます。ただし、明示的に許可されていない変換を要求すると、TRY_CASTはエラーで失敗します。

さて、どの場合にエラーで失敗するかは明確ではありません(関数の全体的なを考えると、類推のようですが、とにかく...)、入力値を変換することでコードを修正できます(何かを使用します)とにかくbigintに収まらないときに巨大な文字列を処理する必要がないので、テーブル内のデータには妥当です。

SELECT TRY_CAST(LEFT(REPLICATE(CONVERT(nvarchar(MAX), N'1'), 4001), 100) AS bigint)

これはNULL値が無効であるため返されますが、エラーが発生することはありません。


-1

値が長すぎる文字列がある場合、インデックスの作成は失敗します。SQL Server 2012を使用して小さなテストコードを試しました。

CREATE TABLE dbo.foo 
(ID bigint not null identity(1,1),
SerializedValue nvarchar(max),
LongValue as TRY_CAST(SerializedValue as bigint));

INSERT INTO dbo.foo (serializedvalue) VALUES(REPLICATE(' ', 4000)+'1');

CREATE INDEX GotToTry ON foo(LongValue);

DROP TABLE dbo.foo;
GO

私の簡単な実験では、nvarchar(max)の値が4000文字以下である限り、コードが機能することがわかりました。(もちろん、末尾に何もないすべての空白は文字に変換されないため、問題なく機能します。)4001番目の文字はString or binary data would be truncatedメッセージをトリガーします。したがって、4000文字を超えるSerializedValueのデータを調べることができます。

編集:はい、変換はBIGINT。問題はないがBIGINT、しかし、ですNVARCHAR(MAX)。例えば:

  1. 行に「1111111111111111111」が含まれている場合は、両方CREATE INDEXで値がに変換されBIGINTます。
  2. 行が0から4000 '1'の場合は可能CREATE INDEXですが、値がNULLオーバーフローしている可能性がありますBIGINT
  3. 行が4000文字より長い場合、CREATE INDEX失敗します。

したがって、NVARCHAR(MAX)の実際の内容がCREATE INDEXにとって重要であるようです。

編集:Jon Seigelは、文字列がnvarchar(4000)よりも長い場合、TRY_CASTがcreate indexでエラーをトリガーすることを特定しました。


2
これは実際には質問の答えにはなりません。インデックスはbigintにあります。それはbigint以外のものになることは決してありません。問題は、bigintがインデックスのサイズの許容範囲内にある場合にデータが切り捨てられるのはなぜか
Mark Sinkinson、2014年

1
@MarkSinkinson編集して詳細を提供。問題はNVARCHAR(MAX)の内容です。
RLF 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.