デフォルトの照合順序がLatin1_General_CI_ASであるデータベースを新しい2014サーバーに移行した後、ほとんどのデータベースの照合順序がLatin1_General_BINである場合、Excelスプレッドシートをインポートしようとすると、次のエラーがスローされます。
私はsysdac_instancesをシステムビューであるmsdbまで追跡しましたが、直接クエリしても同じエラーが発生します。私は誰かがこの問題の簡単な解決策の方向に私を向けることができることを望んでいますか?
不思議なことに、SSMS 2008経由でインポートを実行すると機能します。
sysdac_instances
ビューは次のように定義されています。
CREATE VIEW [dbo].[sysdac_instances]
AS
SELECT
-- this must be locked down because we use instance_id visability as a security gate
case
when (dbo.fn_sysdac_is_currentuser_sa() = 1) then dac_instances.instance_id
when sd.owner_sid = SUSER_SID() then dac_instances.instance_id
else NULL
end as instance_id,
dac_instances.instance_name,
dac_instances.type_name,
dac_instances.type_version,
dac_instances.description,
case
when (dbo.fn_sysdac_is_currentuser_sa() = 1) then dac_instances.type_stream
when sd.owner_sid = SUSER_SID() then dac_instances.type_stream
else NULL
end as type_stream,
dac_instances.date_created,
dac_instances.created_by,
dac_instances.instance_name as database_name
FROM sysdac_instances_internal dac_instances
LEFT JOIN sys.databases sd
ON dac_instances.instance_name = sd.name
ビューは、instance_name
列に対してsys.databases.name
の結合を実行します。 sysdac_instances_internal.instance_name
の列定義では照合順序が指定されていないため、msdbデータベースの照合順序が想定されます。
おそらく、照合がLatin1_General_BIN
であるインスタンスからmsdbを復元したため、照合の競合が発生した可能性があります。それがである場合の場合、MSDBデータベースを再作成する必要があります。これは、その 照合順序は変更できない であるためです。
@Maxは 正しい についてa)このエラーの根本原因(復元されたmsdb
データベースの照合は、master.sys.sysdbreg
のname
フィールドの照合を設定するために使用されるサーバーのデフォルトの照合と一致しません- sys.databases
)のname
フィールドの実際のソース、およびb)理想的にはmsdb
を再構築して、サーバーのデフォルト(Latin1_General_CI_AS
)に一致する照合を取得します。これを実装できるようになるまで、インポートを機能させるには2つの短期的な解決策があります理想的な解決策(そしてはい、私は両方を試しました、そしてそれらはうまくいきます:-):
dbo.sysdac_instances
ビューの定義を変更して、デフォルトの照合の優先順位の動作による競合を回避する照合を明示的に指定します。
ALTER VIEW [dbo].[sysdac_instances]
AS
SELECT
-- this must be locked down because we use instance_id visability as a security gate
case
when (dbo.fn_sysdac_is_currentuser_sa() = 1) then dac_instances.instance_id
when sd.owner_sid = SUSER_SID() then dac_instances.instance_id
else NULL
end as instance_id,
dac_instances.instance_name,
dac_instances.type_name,
dac_instances.type_version,
dac_instances.description,
case
when (dbo.fn_sysdac_is_currentuser_sa() = 1) then dac_instances.type_stream
when sd.owner_sid = SUSER_SID() then dac_instances.type_stream
else NULL
end as type_stream,
dac_instances.date_created,
dac_instances.created_by,
dac_instances.instance_name as database_name
FROM sysdac_instances_internal dac_instances
LEFT JOIN sys.databases sd
ON dac_instances.instance_name = sd.name COLLATE Latin1_General_CI_AS
私はSELECT OBJECT_DEFINITION(OBJECT_ID('dbo.sysdac_instances'));
を使用してその定義をDBから直接プルし、最後にCOLLATE
句を追加しました。
バイナリCollationではなくCOLLATE
句でLatin1_General_CI_AS
Collationを使用して追加したので、この操作(つまり、データベース名のマッチング)は、sys.databases.name
への他の比較と同様に動作します(もちろん、COLLATEを使用してオーバーライドされませんでした)条項;-)
問題のフィールドの照合を変更します。
USE [msdb];
ALTER TABLE dbo.[sysdac_instances_internal]
DROP CONSTRAINT [UQ_sysdac_instances_internal];
ALTER TABLE dbo.[sysdac_instances_internal]
ALTER COLUMN [instance_name] sysname COLLATE Latin1_General_CI_AS NOT NULL;
ALTER TABLE dbo.[sysdac_instances_internal]
ADD CONSTRAINT [UQ_sysdac_instances_internal]
UNIQUE NONCLUSTERED ([instance_name] ASC);
2つのオプションの間で、#1(つまり、ビューの変更)は、基になるテーブルを使用してmsdb
データベース内の他の要素に悪影響を与える可能性が最も低くなります。
インスタンスとデータベースの照合を更新することを検討している場合は、次の投稿を参照してください。
インスタンス、データベース、およびすべてのユーザーデータベースのすべての列の照合順序の変更:何が問題になるのでしょうか?
その他の注意事項:
コードがこの特定のビューを参照していないため、SSMS 2008でインポートが機能した可能性が高いと思います。その振る舞いを説明できる他の違いは考えられません。
バイナリ照合順序を使用する場合は、廃止されたBIN
照合順序ではなく、新しいBIN2
照合順序を使用するのが最適です。
可能な場合は、特定の照合の最新バージョンを使用し、_SC
で終わるバリエーションがある場合はそれを選択することをお勧めします。新しいサーバーの場合は、Latin1_General_100_CI_AS_SC
を選択することをお勧めします。
これは、DATABASE_DEFAULT
と同様の特別な照合がインスタンスレベルで機能する必要がある理由のもう1つの例です。INSTANCE_DEFAULT
により、この種の問題に対する一般的な解決策が存在します。これにより、msdb.dbo.sysdac_instances_internal
テーブルを次のように作成できます。
...
[instance_name] sysname COLLATE INSTANCE_DEFAULT,
...
または、msdb.dbo.sysdac_instances
ビューの最後にこれがある可能性があります。
LEFT JOIN sys.databases sd
ON dac_instances.instance_name = sd.name COLLATE INSTANCE_DEFAULT
したがって、次の提案に投票してください。
COLLATE DATABASE_DEFAULTのように機能するように特別な照合順序INSTANCE_DEFAULTを追加しますが、インスタンスのデフォルトの照合順序を使用します
一般に、照合は互いに一致するように説得できます。私のコメントを見てください:
含まれるDB照合エラー
おそらく、照合に関するコメント、特にCATALOG_DEFAULTは、いくつかの助けになるかもしれません。
2つのデータベース間など、より簡単な照合問題の場合、その説明からのサンプルクエリは次のとおりです。
select NameValue COLLATE DATABASE_DEFAULT from MyDatabase.Schema.Table
EXCEPT
select NameValue COLLATE DATABASE_DEFAULT from TheirDatabase.Schema.Table
このアプローチの価値は、特定の照合を指定する必要がないことですが、COLLATE DATABASE_DEFAULTを使用すると、現在のデータベースの照合を使用できます。これにより、データ照合の問題が解決されます。