stopwords を使用して、一部の単語がフルテキストインデクサーによってスキップされるようにしています。テーブルにストップワードを追加できますsys.fulltext_stopwords。
SQL Server 2012で stopwords および system-stopwords のリストを取得しようとすると、エラーが発生しました。次の(simplified)クエリを実行しています:
SELECT sys.fulltext_stopwords.stopword
FROM sys.fulltext_stopwords
UNION
SELECT sys.fulltext_system_stopwords.stopword
FROM sys.fulltext_system_stopwords;
私が得るエラーメッセージは:
"UNION操作での" Latin1_General_CI_AS "と" Latin1_General_BIN "間の照合の競合を解決できません。"
私のクエリの最初のSELECTステートメントのデータベース collation はLatin1_General_CI_ASです。同じことが master 、 model 、 msdb および tempdb データベースにも当てはまります。
Latin1_General_BINcollation はどこから来たのですか? sys.fulltext_system_stopwordsテーブルの照合順序が異なるようですが、なぜですか?
[〜#〜]編集[〜#〜]:
次のように、クエリで [〜#〜] collate [〜#〜] を使用してエラーを「解決」できます。
SELECT sys.fulltext_stopwords.stopword COLLATE DATABASE_DEFAULT
FROM sys.fulltext_stopwords
UNION
SELECT sys.fulltext_system_stopwords.stopword COLLATE DATABASE_DEFAULT
FROM sys.fulltext_system_stopwords
System-stopwordsが resource database に格納されていることがわかります。これは、照合順序の違いを説明しています。次の質問は次のようになります。なぜリソースデータベースからの照合がデフォルトと異なるのですか?
クエリの最初のSELECTステートメントのデータベース照合順序はLatin1_General_CI_ASです。
まあ、そうではありません。このステートメントにはいくつかの問題があります。
データベースのデフォルトの照合は、文字列リテラル、変数、およびUDFからの戻り値を使用する場合にのみクエリで重要です。さらに、そのデフォルトの照合順序は、列またはCOLLATE
キーワードが使用されていない場合にのみ重要です。
SELECTステートメント/クエリは、全体として、照合順序を使用しません。照合順序は文字列フィールドごとに割り当てられ、クエリのフィールドごとに異なる場合があります。
最初の/最上位クエリの列stopword
は、Latin1_General_CI_AS
照合順序を使用していません(これについては後で詳しく説明します)。
システムストップワードがリソースデータベースに格納されていることがわかります。これにより、照合順序の違いを説明できます。
異なるデータベースからの列(または式)は、必ずしも照合順序の違いを説明しません。上記のように、照合は、フィールドがテーブルの列からのものであるか式であるかに関係なく、クエリの各フィールドごとに設定されます。照合順序は通常、照合順序の優先順位から自然に派生します。列の照合順序はリテラルと変数をオーバーライドし、COLLATE
キーワードは両方をオーバーライドします。競合がある場合、COLLATE
キーワードが必要です。
ただし、ここでの主なポイントは、sys.fulltext_system_stopwords
のstopword
列がリソースデータベースのテーブルの列にある場合(つまり、mssqlsystemresource
)、OR COLLATE
キーワードを介して照合順序が設定されているリソースデータベースのビューの式に由来する場合、リソースデータベースのデフォルトの照合順序は関係ありません。
クエリで
COLLATE
を使用してエラーを「解決」できます
はい、COLLATE
キーワードを使用する方法です。ただし、この競合を修正するには、1つのクエリでCOLLATE
キーワードを指定するだけで済みますが、どのクエリでもかまいません。
たとえば、COLLATE
キーワードなしでクエリを実行すると、次のようになります。
SELECT ftsw.stopword
FROM sys.fulltext_stopwords ftsw
UNION
SELECT ftssw.stopword
FROM sys.fulltext_system_stopwords ftssw;
メッセージ468、レベル16、状態9、行4
UNION操作での「SQL_Latin1_General_CP1_CI_AS」と「Latin1_General_BIN」の照合の競合を解決できません。
したがって、競合が2番目(つまり、一番下)のSELECTステートメントにあると想定すると、現在のDBのデフォルトの照合順序を適用することで修正できます。
SELECT ftsw.stopword
FROM sys.fulltext_stopwords ftsw
UNION
SELECT ftssw.stopword COLLATE SQL_Latin1_General_CP1_CI_AS
FROM sys.fulltext_system_stopwords ftssw;
そしてそれはうまくいきます。しかし、最初の/最上位のSELECTにCOLLATE
を配置するとどうなるでしょうか。
SELECT ftsw.stopword COLLATE SQL_Latin1_General_CP1_CI_AS
FROM sys.fulltext_stopwords ftsw
UNION
SELECT ftssw.stopword
FROM sys.fulltext_system_stopwords ftssw;
それも機能します。そして実際には、次の両方も機能します。
SELECT ftsw.stopword COLLATE Hebrew_100_CI_AS
FROM sys.fulltext_stopwords ftsw
UNION
SELECT ftssw.stopword
FROM sys.fulltext_system_stopwords ftssw;
-- and:
SELECT ftsw.stopword
FROM sys.fulltext_stopwords ftsw
UNION
SELECT ftssw.stopword COLLATE Hebrew_100_CI_AS
FROM sys.fulltext_system_stopwords ftssw;
また、ここではLatin1_General_CI_ASに相当するDATABASE_DEFAULT
オプションを使用するのではなく、Latin1_General_BINを使用します(または、さらに良い方法はLatin1_General_100_BIN2です)。 、これはより新しく、より優れています)この特定のケースでは、「異なる」動作を介して同じ文字列に正規化できるさまざまな文字列が保証されます。 UNION
(ALL
なし)とLatin1_General_CI_AS照合順序の大文字と小文字を区別しないので、照合は別の行として表示されます。
Latin1_General_BIN照合はどこから来たのですか? sys.fulltext_system_stopwordsテーブルの照合順序が異なるようですが、なぜですか?
その照合は、ありそうもないソースからのものです。クエリのシステムカタログビューを見てみましょう。
EXEC sys.sp_help N'sys.fulltext_stopwords';
結果は、これがビュー(予想どおり)であり、stopword
列の照合順序がLatin1_General_BIN(予想外)であることを示しています。 Latin1_General_BIN照合順序がsys.fulltext_stopwords
からのものである場合、sys.fulltext_system_stopwords
についてはどうですか。また、他の照合順序はどこから来るのでしょうか。見てみよう:
EXEC sys.sp_help N'sys.fulltext_system_stopwords';
結果は、これがビュー(予想どおり)であり、stopword
列の照合順序がSQL_Latin1_General_CP1_CI_AS(予想外)であることを示しています。
ここで、これらの各システムカタログビューの定義についてもう少し詳しく説明します。
EXEC sys.sp_helptext N'sys.fulltext_stopwords';
返品(簡略化):
SELECT
fts.stopword,
FROM sys.sysftstops fts
その後:
EXEC sys.sp_help N'sys.sysftstops';
結果は、これがシステムテーブルであり、stopword
列が実際に照合順序Latin1_General_BINを持っていることを示しています。
次に、他のシステムカタログビューに移動できます。
EXEC sys.sp_helptext N'sys.fulltext_system_stopwords';
返品(簡略化):
SELECT convert(nvarchar(64), stopword) as stopword, language_id
FROM OpenRowset(TABLE FTSYSSTPWD)
FTSYSSTPWD
はリソースデータベースから取得されているため、現時点でできることはこれ以上ありません。
それでも、リソースデータベースからのデータの照合順序を明確にするために最後にできることが1つあります-sys.fulltext_system_stopwords.stopword
:
CREATE DATABASE [FullTextCollationTest] COLLATE SQL_EBCDIC277_CP1_CS_AS;
GO
USE [FullTextCollationTest];
EXEC sys.sp_help N'sys.fulltext_stopwords';
-- Collation for [stopword] column: Latin1_General_BIN (same as before)
EXEC sys.sp_help N'sys.fulltext_system_stopwords';
-- Collation for [stopword] column: SQL_EBCDIC277_CP1_CS_AS (same as DB's default Collation)
GO
USE [master];
DROP DATABASE [FullTextCollationTest];