COLLATE
とUNION
を併用するには2つのテーブルを結合したい(両方に同じ列と同じ型がある:varchar,int, int, decimal
)。
次のエラーが発生しました:
sg 468、レベル16、状態9、行1 UNION操作での「Serbian_Latin_100_CI_AS」と「Croatian_CI_AS」の間の照合の競合を解決できません。
私のSQLステートメント:
select * from #IA_BIH
union
select * from #IA_MNE
どこに挿入するべきですかcollate database_default
?さまざまな組み合わせを試しましたが、うまくいきませんでした。
照合名に基づいて、Microsoft SQL Serverを使用していると想定しています。
COLLATEは、データベースレベルまたは列レベルで使用できます。 2つのテーブルをUNIONしようとしているため、必要な列で列照合を使用すると、クエリが解決されます。
ここにあなたを助けるためのコードのサンプルビットがあります:
use testdb
GO
CREATE TABLE dbo.Serbian (Name VARCHAR(20) COLLATE Serbian_Latin_100_CI_AS);
CREATE TABLE dbo.Croatian (Name VARCHAR(20) COLLATE Croatian_CI_AS);
GO
INSERT INTO dbo.Serbian VALUES ('serbian');
INSERT INTO dbo.Croatian VALUES ('croation');
GO
-- Collate to a particular named collation
SELECT Name COLLATE Serbian_Latin_100_CI_AS as CollatedNameSerbian from dbo.Serbian
UNION ALL
SELECT Name COLLATE Serbian_Latin_100_CI_AS from dbo.Croatian
GO
-- Collate to the database default collation
SELECT Name COLLATE database_default as CollatedNameDBDefault from dbo.Serbian
UNION ALL
SELECT Name COLLATE database_default from dbo.Croatian
GO
DROP TABLE dbo.Serbian;
DROP TABLE dbo.Croatian;
GO
もちろん、照合が競合する列がいくつかある場合は、それらの照合も定義する必要があります。
照合は、特にVARCHAR
データの場合、少しトリッキーになる可能性があります。 NVARCHAR
データとVARCHAR
データの両方について、照合順序は並べ替えと比較のルールを制御します。ただし、VARCHAR
データの場合、照合順序は文字セット(つまり、各8ビット値が表す文字を決定するために使用されるコードページ)も制御します。したがって、VARCHAR
data canの照合順序を変更すると、データが失われます。
_SELECT CHAR(230) AS [DB-Collation],
CHAR(230) COLLATE Korean_100_CI_AS AS [Korean],
CHAR(230) COLLATE Albanian_CI_AS AS [Albanian],
CHAR(230) COLLATE Greek_100_CI_AS AS [Greek];
-- æ a ?
_
ただし、照合順序の不一致があるため、そのうちの1つを変更する必要があります。この特定のケースでは_database_default
_を使用しないことをお勧めします。これは、クエリの実行元のデータベースに関連するため、動作に一貫性がなくなる可能性があるためです。
幸い、エラーで言及されている両方の照合順序には同じコードページ1250があります。次のクエリを使用して、この情報を見つけることができます。
_SELECT col.[name], COLLATIONPROPERTY(col.[name], 'CodePage') AS [CodePage]
FROM sys.fn_helpcollations() col
WHERE [name] IN (N'Serbian_Latin_100_CI_AS', N'Croatian_CI_AS');
_
この時点で、これらの2つのうち1つを選択して、もう1つを強制的に同じにする必要があります。両方の照合順序が同じコードページを使用するため、選択は使用されている文字セットに影響しません。考慮する必要がある唯一の違いは、セルビア語とクロアチア語の並べ替えと比較のルールです。エンドユーザーの期待に最も近いものを選択してください。
1つのオプションは、@ RLFの回答に示されているように、SELECT
ステートメントで照合を強制することです。ここでの欠点は、_SELECT *
_を使用できなくなることです(これがストアドプロシージャのコードである場合は、とにかく_SELECT *
_を使用しないことをお勧めします)。
別のオプションは、一時テーブルを作成するときに_CREATE TABLE
_または_SELECT INTO
_を使用して行われるかに関係なく、これらのテーブルのいずれかに照合を強制することです。
_SELECT ac.*
FROM sys.all_columns ac
WHERE ac.[object_id] = OBJECT_ID(N'sys.objects')
AND ac.[name] = N'name';
-- SQL_Latin1_General_CP1_CI_AS (on my system, at least)
SELECT [name] COLLATE Hebrew_100_CI_AS AS [name]
INTO #coltest
FROM sys.objects;
SELECT sc.*
FROM [tempdb].sys.columns sc
WHERE sc.[object_id] = OBJECT_ID(N'tempdb..#coltest');
-- Hebrew_100_CI_AS
_
ここでの利点は、次のことができることです。
UNION
クエリで_SELECT *
_を使用します。COLLATE
オプションを追加する必要なく、これらのテーブルに対していくつかのクエリを実行します。また、_CREATE TABLE
_または_SELECT INTO
_が実行されているデータベースのデフォルトの照合順序が、エラーメッセージに示されている2つの照合順序の1つであると想定すると、先に進んで_COLLATE database_default
_。