none
データセットで末尾のスペース文字を区別するには? RRS feed

  • 質問

  • お世話になっております。

    XMLに保存したデータを型付データセットで保持するということをしているのですが、String型のフィールドにおいて、末尾にスペースが無い文字列と、スペースがある文字列が同じ文字列と扱われてしまいます。(環境は.NET Framework2.0)

    例えば、一意制約を設定したフィールド”key_col”と制約なしのフィールド"data_col"があるテーブルの場合、

    key_col
    data_col
    hoge ほげ
    hoge△ ほげ△
    hoge△△ ほげ△△
    ※△:半角スペース

    上記のkey_col列のデータはすべて同じ文字とみなされ、一意制約違反となってしまいます。
    また、data_col列を'ほげ△'で抽出した場合、3行すべてがヒットしてしまいます。
    # ちなみに、先頭にスペースがある文字列は、違う文字として扱われるようです。

    末尾にスペースがある文字列と、スペースが無い文字を区別したいのですが、このような事は可能でしょうか?
    • 編集済み nabejiru 2009年8月24日 2:33
    2009年8月24日 1:47

回答

  • 比較する際に末尾の空白文字を無視するってのは DataTable の仕様です。SQL に合わせた挙動みたいですね。
    恐らくこの仕様は変更することは不可能です。
    • 回答としてマーク nabejiru 2009年8月24日 5:26
    2009年8月24日 2:59

すべての返信

  • 比較する際に末尾の空白文字を無視するってのは DataTable の仕様です。SQL に合わせた挙動みたいですね。
    恐らくこの仕様は変更することは不可能です。
    • 回答としてマーク nabejiru 2009年8月24日 5:26
    2009年8月24日 2:59
  • >Hongliangさん

    早速の回答を頂きまして、誠にありがとうございます。
    比較する際に末尾の空白文字を無視するってのは DataTable の仕様です。SQL に合わせた挙動みたいですね。
    恐らくこの仕様は変更することは不可能です。
    根本的な仕様の問題なのですね。。。(「SQL」とは「SQL Server」のことでしょうか?)
    標準機能での対応は諦めて、独自に処理を実装して対応しようと思います。

    # 具体的には、型付データセットでオーバーライドしたOnOnColumnChanging()メソッド内に一意制約違反の検証処理を実装。
    # 抽出処理は、新たにメソッドを追加して実装しようと思います。
    • 編集済み nabejiru 2009年8月24日 5:10
    2009年8月24日 5:08
  • SQL とは SQL-92 の仕様の事を言っているのだと思います。

    INF: How SQL Server Compares Strings with Trailing Spaces
    http://support.microsoft.com/kb/316626/en-us

    どのように SQL Server と比較 INF: 末尾のスペースを持つ文字列
    http://support.microsoft.com/kb/316626/ja

    SQL Server 2008 オンライン ブック (2009 年 5 月)

    K.Oumi
    2009年8月24日 5:41
  • >K.Oumiさん
    SQL とは SQL-92 の仕様の事を言っているのだと思います。
    ご指摘ありがとうございます。

    データセットやSQL Serverに限らず、他のデータベースでも同じような事が起こり得えると・・・。
    今後の開発の際も気をつけないといけませんね。

    リンクがとても参考になりました。ありがとうございました。
    2009年8月24日 8:23
  • 列の型をObject型にしてしまうのはどうでしょう。
    その列の読み書きをString型のプロパティ経由で行えば型付DataSetにみえなくもない。
    #データセットデザイナで作られたDataSetを手書きで修正したりする手間が増えたり、スキーマを書き出すとObject型になってたりしますが…

    以下DataTable1RowのDataColumn1列を変更する場合
    /// <summary>こっちがデザイナで作成される列</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] //追加
    [System.Xml.Serialization.XmlIgnore()] //追加
    private object DataColumn1_ //privateに
    {
        get
        {
            try
            {
                return ((object)(this[this.tableDataTable1.DataColumn1Column]));
            }
            catch (global::System.InvalidCastException e)
            {
                throw new global::System.Data.StrongTypingException("テーブル \'DataTable1\' にある列 \'DataColumn1\' の値は DBNull です。", e);
            }
        }
        set
        {
            this[this.tableDataTable1.DataColumn1Column] = value;
        }
    }
    
    /// <summary>こっちが手書きで追加した列</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.Xml.Serialization.XmlElement("DataColumn1")]
    public string DataColumn1
    {
        get
        {
            return (string)this.DataColumn1_;
        }
        set
        {
            this.DataColumn1_ = value;
        }
    }
    • 回答としてマーク nabejiru 2009年8月26日 1:49
    • 回答としてマークされていない nabejiru 2009年8月26日 1:49
    2009年8月24日 11:47
  • >gekkaさん
    ありがとうございます。

    デザイナでObject型のフィールドを作成して、[データセット].designer.csに手書きで編集を加える、ということでしょうか?
    2009年8月26日 2:07
  • string型にするプロパティの部分はPartialのほうに記述してしまえばいいです。

    object型のプロパティは属性をつけないといけないのでdesigner.csに手を入れることになります。

    私が属性を書き換えるときはdesigner.csの全部を別のファイルにコピーしてしまって、コピーしたコードのほうに属性を付けてます。
    重複することになるdesigner.csはコンパイルしないに設定してます。
    デザイナを修正するたびにコピーして設定の手間が発生します。

    #partialで属性だけ操作できると楽なのですが・・・
    2009年8月26日 3:59
  • >gekkaさん
    string型にするプロパティの部分はPartialのほうに記述してしまえばいいです。

    object型のプロパティは属性をつけないといけないのでdesigner.csに手を入れることになります。

    私が属性を書き換えるときはdesigner.csの全部を別のファイルにコピーしてしまって、コピーしたコードのほうに属性を付けてます。
    重複することになるdesigner.csはコンパイルしないに設定してます。
    デザイナを修正するたびにコピーして設定の手間が発生します。

    #partialで属性だけ操作できると楽なのですが・・・
    なるほど。
    デザイナで編集するとdesigner.csがクリアされるので、ひと工夫必要ですね。
    私もpartialの方にobject型と、string型の両方を記述する事も考えてみましたが、
    テーブルの列として扱ってくれないので、ボツとしました。

    gekkaさんには大変申し訳ないのですが、時間が無かったため、抽出・一意制約違反のチェックを独自に行うことで対応しました。
    貴重なご意見を頂き誠にありがとうございました。

    2009年8月27日 1:16