varcharとnvarcharのデータを使用した「順序付け」の結果の間に予期しない違いが発生しました。どちらの場合も、問題のデータは古いASCII文字セットからのものです。 nnn vs -nnnで始まるデータの順序付けに差が生じます.nは数字です。varcharとnvarcharのSQL Serverの予期しない「順序付け」の差異
以下は、問題を再現するSQL Serverスクリプトです。私のテストサーバーはSQL 2016ですが、私は2008年と2012年にも問題を再現しました。私は何の効果もない別の照合を試みました(Latin1_General_binを除く、以下を参照)。このスクリプトでは、アプリケーションに似た2つのサンプルテーブルを作成します.1つはvarcharともう1つのnvarcharを使用し、7つのデータ行を追加します。
CREATE TABLE [dbo].[_ValidationLists](
[_FldNum] [int] NOT NULL,
[_ValidationEntry] [varchar](250) NOT NULL,
CONSTRAINT [PK__ValidationLists] PRIMARY KEY CLUSTERED
(
[_ValidationEntry] ASC,
[_FldNum] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[_ValidationListsN](
[_FldNum] [int] NOT NULL,
[_ValidationEntry] [nvarchar](250) NOT NULL,
CONSTRAINT [PK__ValidationListsN] PRIMARY KEY CLUSTERED
(
[_ValidationEntry] ASC,
[_FldNum] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO [_ValidationLists] (_fldnum, _ValidationEntry) VALUES (1,'-1'), (1,'-10'), (1,'-100'), (1,'0'), (1,'1'), (1,'10'), (1,'100')
INSERT INTO [_ValidationListsN] (_fldnum, _ValidationEntry) VALUES (1,N'-1'), (1,N'-10'), (1,N'-100'), (1,N'0'), (1,N'1'), (1,N'10'), (1,N'100')
select * from [_ValidationLists]
order by [_ValidationEntry] asc
select * from [_ValidationListsN]
order by [_ValidationEntry] asc
select文の結果は次のとおりです。 varcharの最初の結果は、私が期待しているものです(辞書順ソート)。私が説明することができない2番目の結果。 1つ目は、顧客ベースも期待していることであり、私たちはこの結果によって驚かされました。 (顧客データは珍しい - 通常、この表はアルファデータに使用され、アルファデータ注文はvarcharとnvarcharの両方で同じです)。
結果は、N '...'を使用して_ValidationListsN行を初期化するのと同じです。元のデータには、「-100:合格」などの長い記入項目がありました。私は、問題を示すデータを少なくとも編集しました。
すべてのエントリが同じ長さになるように、ブランクを使った右パディングは効果がありません。
COLLATEの使用Latin1_General_binは辞書順ソートを再現しますが、(1つの理由のみで)大文字小文字を区別しないソートを使用するため、受け入れられません。
この問題を報告したカスタマーにはASCIIデータしかないので、varcharを使用してこのテーブルを再作成して修正することができます。私は結果が私には間違っているように見えるので、nvarcharがこのように動作する理由を知りたいと思っています。また、私たちが期待する注文行動を得る方法がある場合(最初のケース)。少なくとも、私は ' - '(ASCII 0X2d、ダッシュまたはマイナス記号)で始まるすべてのエントリが一緒に注文しないのはなぜか分かりません。
_FldNum _ValidationEntry
1 -1
1 -10
1 -100
1 0
1 1
1 10
1 100
(7行(複数可)の影響を受ける)
_FldNum _ValidationEntry
1 0
1 1
1 -1
1 10
1 -10
1 100
1 -100
(影響7行(複数可))
データが数値の場合は、数値データ型を使用してください。 – HLGEM
データは一般的に英数字です。実際の顧客データ項目では、 '-123:Pass'のようになります。私は効果を示す最小限のデータを煮詰めました。 – RFaneuf