WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

SQL Server の Order By での濁音の扱い

by WebSurfer 2017年12月15日 16:10

SQL Server のデフォルトでの照合順序 Japanese_CI_AS で、Order By 句による濁音の並び順がどうなるかについて書きます。元の話は teratail のスレッド半角の「濁音なし」「濁音あり」カナのソート順についてです。

照合順序 Japanese_CI_AS

照合順序 Japanese_CI_AS の場合の結果は上の画像の通りです。濁音はアクセントとして扱われ、'キ' と 'ギ' および 'キ' と 'ギ' は Order By 句では同じ順序となり、「クロギアイコ」は「クロキマユ」より前に、「クロギアイコ」は「クロキマユ」より前になっているのが分かるでしょうか。

半角カナの 'ギ' は、実際は 2 つの文字 'キ' (U+FF77) と '゙' (U+FF8D) を合わせたものなのですが、にもかかわらず「クロギアイコ」は「クロキマユ」より前になるのが不思議でした。

その理由は、MSDN Blogs の記事「日本語照合順序での 濁音、半濁音 の取り扱いについて」に書いてありますが、日本語照合順序を使用している場合 '半角文字' + '濁音' または '半濁音' が 1 文字として認識されるからだそうです。

つまり、Order By では濁点がないのと同じ扱いになり、照合順序に _WS の指定がないので全角・半角の区別をせず、上の画像の様な結果となるということのようです。

ちなみに、照合順序を Japanese_BIN2 にして Order By 句を適用すると以下の画像の順序になります。

照合順序 Japanese_BIN2

BIN2 というのは "すべての文字をコードポイントによる比較を行います" とのことです。詳しくは、MSDN Blogs の記事「照合順序 – 文字の比較と並び順 (その 1)」を見てください。

--------------------------------------------

以下にオマケで、Linq で OrderBy を使った時どうなるかという話を書いておきます。これも元は teratail の別スレッドでの話です。

単純に words.OrderBy(s => s); としたときは SQL Server で照合順序を Japanese_CI_AS とした時と同じになります。

カスタム Comparer を定義し、それを OrderBy の第 2 引数に使えば何とでもできるはずです。SQL Server の照合順序 Japanese_BIN2 と同じ結果になるようにするには、String.CompareOrdinal メソッド(それぞれの文字列の対応する Char オブジェクトの数値を評価することで、2 つの String を比較)が使えそうです。

以下のコードで検証した限りですが、望む結果が得られました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    public class StringCompareOrdinal : IComparer<string>
    {
        public int Compare(string x, string y)
        {
            return string.CompareOrdinal(x, y);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            string[] words = { "the", "quick", "brown", 
                "fox", "jumps","クロキマユ", "クロギアイコ", 
                "クロギトミオ", "テスト 項目", "クロキマユ", 
                "クロギアイコ", "クロギトミオ" };

            var query = words.OrderBy(s => s);

            foreach (string s in query)
                Console.WriteLine(s);
            Console.WriteLine("-------------------");

            var query2 = words.OrderBy(s => s, 
                               new StringCompareOrdinal());

            foreach (string s in query2)
                Console.WriteLine(s);

            /*
            結果は:
            brown
            fox
            jumps
            quick
            the
            クロギアイコ
            クロギアイコ
            クロギトミオ
            クロギトミオ
            クロキマユ
            クロキマユ
            テスト 項目
            -------------------
            brown
            fox
            jumps
            quick
            the
            クロキマユ
            クロギアイコ
            クロギトミオ
            テスト 項目
            クロキマユ
            クロギアイコ
            クロギトミオ
            */
        }
    }
}

Tags: , ,

SQL Server

SSMS の楽観的同時実行制御

by WebSurfer 2017年2月11日 15:52

SQL Server Management Studio(以下、SSMS と書きます) を使ってデータの編集ができますが、その際に楽観的同時実行制御がかかっているようです。(SQL Server 2008 Express SP4 で試しました)

SSMS の楽観的同時実行制御

上の画像が SSMS を使ってのデータの編集中に楽観的同時実行制御に引っかかって警告のダイアログが表示されたところです。

上の例は、EmployeeID = 1 の LastName を編集して他の行に移動した際、編集されたデータを使ってデータベースの更新(UPDATE クエリの発行)をトライしたが、SSMS にデータを表示してから UPDATE クエリが発行されるまでの間に他のユーザーがデータを変更していたという状況です。

SSMS での編集に楽観的同時実行制御がかかるって知ってました? 実は自分は知らなかったです。後勝ちルールになると思ってました。(汗)

このデータを更新するアプリと SSMS を一緒に動かしていたら上の画像のダイアログが出てきたので、楽観的同時実行制御がかかっていることを初めて知ったという次第です。

新発見ということでブログに書いておくことにしました。知らなかったのは自分だけかもしれませんが。(笑)

Tags: ,

SQL Server

SQL Server 接続プロトコル順序

by WebSurfer 2016年11月16日 23:43

SQL Server の接続プロトコルとして (1) 共有メモリ、(2) TCP/IP、(3) 名前付きパイプが有効になっている場合、どの順序で接続をトライするかという話を書きます。

SQL Server の Protocol Order

元は MSDN Forum の「アプリケーションからSQLServerへの接続プロトコル(名前付きパイプ)について」という表題のスレッドでの話です。

MSDN Forum で回答を書くためググって調べて見つけた記事 SQL Server clients may change protocols when the client computers try to connect to an instance of SQL Server に書いてあったことですが、レジストリの ProtocolOrder で指定されている順番で接続をトライするとのことです。

確かに自分の PC(SQL Server 2005 Developer Edition と SQL Server 2008 Express がインストールされています)のレジストリを見ると、上の画像のような設定がありました。

レジストリの設定は変えてないので、デフォルトで sm tcp np の順、即ち、(1) 共有メモリ ⇒ (2) TCP/IP ⇒ (3) 名前付きパイプの順に接続をトライしていくようです。(実際にその順番で接続をトライしているかは確認していませんが)

MSDN Forum の質問者さんのケースでは「時々名前付きパイプで接続しにいき失敗している」ということでしたが、時々何らかの問題で TCP/IP の接続に失敗した後、最後に名前付きパイプで接続に行って失敗し、「SQL Server への接続を確立しているときに・・・ (provider: 名前付きパイプ プロバイダ・・・」というエラーメッセージになったものと思われます。

Tags:

SQL Server

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2018年4月  >>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

View posts in large calendar