DOBON.NETプログラミング道掲示板

[ 最新記事及び返信フォームをトピックトップへ ]

■34169 / inTopicNo.1)  ポルトガル語の登録
  
□投稿者/ あばば無人君 一般人(1回)-(2019/02/28(Thu) 18:08:02)
  • アイコン環境/言語:[Win10Pro(Ver1809)、SQLServer2017、C#(.Net4.7.1)] 
    分類:[.NET] 

    DB(SQLServer2017)も絡む質問なのでこちらへ投稿して良いか分からなかったのですが、
    いくら調べても手掛かりが無いので投稿させて頂きました。

    現在Win10Pro(Ver1809)+SQLServer2017+C#(.Net4.7.1)の環境でアプリケーション構築を行っております。
    このアプリケーションでは画面のテキストボックスにはポルトガル語が入力されるのですが、
    DBに登録するとポルトガル語のアクセント記号が消えてアルファベットのみになってしまいます。
    ※アクセント記号について:https://www.porgoru.com/213.html

    DBテーブルの対象カラムは型をNVARCHARにして、INSERT文には「N'あたい'」の実装も行っており、
    中国語や韓国語は問題無く登録出来ていることを確認しています。
    ポルトガル語でアクセント記号も込みで登録するにはこの対応以外にも必要な何かがあるのでしょうか?

    C#での多言語アプリケーションに詳しい方、いらっしゃいましたらお力添え頂きたいです。
    どうか宜しくお願い致します。

マルチポストを報告
違反を報告
引用返信 削除キー/
■34172 / inTopicNo.2)  Re[1]: ポルトガル語の登録
□投稿者/ 魔界の仮面弁士 大御所(1209回)-(2019/02/28(Thu) 19:18:02)
  • アイコン
    No34169に返信(あばば無人君さんの記事)
    > DBに登録するとポルトガル語のアクセント記号が消えてアルファベットのみになってしまいます。
    
    SqlParameter の SqlDbType が Text になっていたりはしませんか?
    
    たとえば下記の場合、
    パターン 1 と 3 では正常に書き込まれますが、
    パターン 2 の時にはアクセント記号が失われます。
    
    
    using Dapper;
    using System.IO;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    
    /*
    CREATE TABLE Test (
      Id int NOT NULL PRIMARY KEY,
      Message nvarchar(MAX) NULL
    )
    */
    namespace ConsoleApp01
    {
        class Program
        {
            static void Main()
            {
                string 葡語 = "Com licen\u00E7a, voc\u00EA pode falar Portugu\u00EAs?";
    
                string sql = "INSERT INTO Test (Id, Message) VALUES (@Id, @Message)";
    
                using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
                {
                    con.Open();
                    con.Execute("TRUNCATE TABLE Test");
    
                    // パターン1
                    con.ExecuteScalar(sql, new { Id = 1, Message = 葡語 });
    
                    // パターン2
                    using (var cmd = con.CreateCommand())
                    {
                        cmd.CommandText = sql;
                        cmd.CommandType = CommandType.Text;
                        cmd.Parameters.Add("@Id", SqlDbType.Int).Value = 2;
                        cmd.Parameters.Add("@Message", SqlDbType.Text).Value = 葡語;
                        cmd.ExecuteNonQuery();
                    }
    
                    // パターン3
                    using (var cmd = con.CreateCommand())
                    {
                        cmd.CommandText = sql;
                        cmd.CommandType = CommandType.Text;
                        cmd.Parameters.Add("@Id", SqlDbType.Int).Value = 3;
                        cmd.Parameters.Add("@Message", SqlDbType.NText).Value = 葡語;
                        cmd.ExecuteNonQuery();
                    }
    
                    // 確認のため、書き込んだ結果を DataSet に SELECT しなおしてからファイルに保存
                    using (var ds = new DataSet("Example"))
                    using (var adp = new SqlDataAdapter("SELECT * FROM Test ORDER BY Id", con))
                    {
                        adp.Fill(ds, "Test");
    
                        var q = ds.Tables["Test"].AsEnumerable().Select(
                            r => $"{r["Id"]}\t{r["Message"]}");
    
                        File.WriteAllLines(@"C:\TEMP\test.txt", q, Encoding.UTF8);
    
                        ds.WriteXmlSchema(@"C:\TEMP\test.schema.xml");
                        ds.WriteXml(@"C:\TEMP\test.xml");
                    }
    
                    con.Close();
                }
            }
        }
    }

違反を報告
引用返信 削除キー/
■34173 / inTopicNo.3)  Re[2]: ポルトガル語の登録
□投稿者/ あばば無人君 一般人(2回)-(2019/03/01(Fri) 10:14:41)
  • アイコンNo34172に返信(魔界の仮面弁士さんの記事)
    > SqlParameter の SqlDbType が Text になっていたりはしませんか?
    >
    > たとえば下記の場合、
    > パターン 1 と 3 では正常に書き込まれますが、
    > パターン 2 の時にはアクセント記号が失われます。

    非常に分かりやすいサンプル、ありがとうございます。
    そして参画している案件のSQL発行方式では非常にまずいことがわかりました・・・。

    当案件ではINSERT文を発行する時は
    string sql = "INSERT INTO Test (Id, Message) VALUES (1, N'ポルトガル語')";
    cmd.CommandText = sql;
    cmd.ExecuteNonQuery();
    という風にパラメータを使用せず、直にVALUESの文字列まで含めたSQLを生成しています。

    この発行方式ですとnvarcharカラムのデフォルトのSqlDbTypeが「Text」になってしまう様ですね・・・。

    発行方式の変更をプロジェクトメンバーと検討しようと思います。
    本当にありがとうございました。

    しかし質問しておいてなんですが、何故この様な知識をお持ちなのでしょうか?
    私は「SQLServer 2017 C# ポルトガル語 登録 アクセント記号 消える」のキーワードで
    検索しても1件もヒットしなかったので不思議です。

違反を報告
引用返信 削除キー/
■34174 / inTopicNo.4)  Re[3]: ポルトガル語の登録
□投稿者/ 魔界の仮面弁士 大御所(1210回)-(2019/03/01(Fri) 10:39:35)
  • アイコンNo34173に返信(あばば無人君さんの記事)
    > 当案件ではINSERT文を発行する時は
    > string sql = "INSERT INTO Test (Id, Message) VALUES (1, N'ポルトガル語')";
    > cmd.CommandText = sql;
    > cmd.ExecuteNonQuery();
    > という風にパラメータを使用せず、直にVALUESの文字列まで含めたSQLを生成しています。


    妙ですね。

    当方環境で追試験してみましたが、下記の 4 や 5 では問題ありませんでした。
    6 については、アクセント記号が失われて
     "Com licenca, voce pode falar Portugues?"
    になってしまいましたけど…。


    // パターン4(非推奨)
    using (var cmd = con.CreateCommand())
    {
     cmd.CommandText = $"INSERT INTO Test (Id, Message) VALUES (4, N'{葡語}')";
     cmd.CommandType = CommandType.Text;
     cmd.ExecuteNonQuery();
    }

    // パターン5(非推奨)
    con.ExecuteScalar($"INSERT INTO Test (Id, Message) VALUES (5, N'{葡語}')");

    // パターン6(非推奨)
    con.ExecuteScalar($"INSERT INTO Test (Id, Message) VALUES (6, '{葡語}')");


    > この発行方式ですとnvarcharカラムのデフォルトのSqlDbTypeが「Text」になってしまう様ですね・・・。
    いや、そもそも SqlParameter を使っていないのなら、SqlDbType は関係ないです。


    > しかし質問しておいてなんですが、何故この様な知識をお持ちなのでしょうか?
    知識なんて無いですよ。検索もしていません。

    質問を受けて、実際に何パターンかで検証してみようと、
    先のコードを書いてみただけのことです。
    ポルトガル語がどんなものかも知りませんでしたので、
    挿入するサンプル文も、Google 翻訳で適当な文章をでっち上げただけですし。
違反を報告
引用返信 削除キー/
■34175 / inTopicNo.5)  Re[4]: ポルトガル語の登録
□投稿者/ 魔界の仮面弁士 大御所(1211回)-(2019/03/01(Fri) 11:15:24)
  • アイコン
    No34174に返信(魔界の仮面弁士さんの記事)
    > 妙ですね。
    > 当方環境で追試験してみましたが、下記の 4 や 5 では問題ありませんでした。
    
    NVARCHAR 列に照合順序を明示した場合もテストしてみたので、一応参考までに。
    なお、当方データベースの照合順序は [Japanese_BIN] です。
    
    /*
    
    CREATE TABLE Example
    (
      Id int NOT NULL PRIMARY KEY,
      Msg1 nvarchar(MAX)                                NULL,
      Msg2 nvarchar(MAX) COLLATE Japanese_CI_AS         NULL,
      Msg3 nvarchar(MAX) COLLATE Japanese_BIN2          NULL,
      Msg4 nvarchar(MAX) COLLATE Japanese_XJIS_100_BIN2 NULL,
      Msg5 nvarchar(MAX) COLLATE Japanese_Unicode_BIN2  NULL
    )
    
    */
    
    
    string 葡語 = "Com licen\u00E7a, voc\u00EA pode falar Portugu\u00EAs?";
    
    string template1 = "INSERT INTO Example (Id, Msg1, Msg2, Msg3, Msg4, Msg5) VALUES ({0}, N'{1}', N'{1}', N'{1}', N'{1}', N'{1}')";
    string template2 = "INSERT INTO Example (Id, Msg1, Msg2, Msg3, Msg4, Msg5) VALUES ({0},  '{1}',  '{1}',  '{1}',  '{1}',  '{1}')";
    
    
    // 下記では、すべての列でアクセント記号が維持されていた。
    string sql1 = string.Format(template1, 1, 葡語);
    
    // 下記では、すべての列でアクセント記号が失われていた。
    string sql2 = string.Format(template2, 2, 葡語);

違反を報告
引用返信 削除キー/
■34176 / inTopicNo.6)  Re[5]: ポルトガル語の登録
□投稿者/ あばば無人君 一般人(3回)-(2019/03/01(Fri) 12:02:32)
  • アイコンNo34175に返信(魔界の仮面弁士さんの記事)
    >>妙ですね。
    >>当方環境で追試験してみましたが、下記の 4 や 5 では問題ありませんでした。

    本当に申し訳ありません。上記の通り問題無く、こちらの試験環境が原因でした。
    再度他言語化対応アプリケーションを試験環境へアップして確認したら問題ありませんでした。

    昨日は私が多言語化対応の調査のために試験環境を占有して使用するはずでしたが、
    私が休憩で離席した時に他の開発員が自前でビルドした実行体を勝手に試験環境へ
    アップしていました。(報告するか、せめて戻してくれていれば・・・)

    こんなくだらないことで魔界の仮面弁士さんのお時間を取らせてしまい本当に申し訳ありませんでした。



    >>知識なんて無いですよ。検索もしていません。
    >>
    >>質問を受けて、実際に何パターンかで検証してみようと、
    >>先のコードを書いてみただけのことです。

    質問から1時間ちょっとであれだけのパターンを検証されたのですね。驚嘆の一言です。
    私も魔界の仮面弁士さんに近づけるように精進致します。



違反を報告
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

Mode/  Pass/


- Child Tree -