77867


CSVファイルをSQLServerに取り込もうとしています。

データベース内のカラムが「char(2)not
null」で定義しているカラムにデータを挿入する際、CSV上では半角スペース2文字のカラムがnullと判定されてしまい、以下のメッセージがスローされてしまいます。

[code]

    Column 'ColumnNameX' で DBNull.Value を使用できません。
    
[/code]

CSVファイルの中では (こんな感じで `" "` )
ダブルクォーテーションで囲い、明示的に空白であることを示したつもりなのですが、空白を空白として処理するのには何かオプションの指定があるのでしょうか？

[code]

    public static void DoConnect()
    {
        //接続文字列の構成
        string connectionString = @"Driver={Microsoft Text Driver (*.txt; *.csv)}; DBQ=.\";
        string dbStr = @"Persist Security Info = False; database = MYDB; server = localserver; UID = sa; PWD = xxxxxx;";
    
        using (OdbcConnection conn = new OdbcConnection(connectionString))
        {
            try
            {
                //データベース接続のOpen
                conn.Open();
    
                //CSVを読む
                OdbcCommand command = new OdbcCommand("SELECT * FROM TABLE_NAME.csv", conn);
                OdbcDataReader reader = command.ExecuteReader();
                //データ型をキチンとするならSchemaを使う事！
                //DataTable t = reader.GetSchemaTable();
    
                //入れ込む先のDBへ接続
                using (SqlConnection scon = new SqlConnection(dbStr))
                {
                    //接続
                    scon.Open();
                    SqlTransaction trn = scon.BeginTransaction();   //トランザクション開始
                    try
                    {
                        SqlBulkCopy copy = new SqlBulkCopy(scon, SqlBulkCopyOptions.KeepNulls, trn);  //コピーするときにトランザクションを結びつける
                        copy.DestinationTableName = "TABLE_NAME";
                        //そのままダイレクトに入れ込むべし
                        copy.WriteToServer(reader);     //★★★★　半角スペースがnullになってしまう
    
                        trn.Commit();                                   //コミット                        
                    }catch(SqlException ex)
                    {
                        trn.Rollback();
                    }
                    catch(Exception ex)
                    {
                        trn.Rollback();
                    }
                }
            }
            finally
            {
                if (conn != null)
                {
                    conn.Close();
                }
            }
        }
    }
    
[/code]

**追記:**

最初の質問に以下のようなコードを追加して取得してきたデータの中身を確認したところ、半角スペースのところがnullで読み込まれていました。

半角スペースをNULLではなく、半角スペースのまま読み込むことは出来ないでしょうか。

[code]

    DataTable t = new DataTable();
    t.Load(reader);
    
    //結果表示
    foreach (DataRow row in t.Rows)
    {
        foreach (object item in row.ItemArray)
        {
            Console.Write(item.ToString() + ",");
        }
        Console.WriteLine(" ");
    }
    
[/code]


CC BY-SA 4.0
2021-06-24T11:28:36.773
77761
2021-06-29T22:59:16.600
2021-06-29T00:44:00.243
3060
15047
question
c#
CSVを読み込む際、半角スペースがnullに変換されてしまう


あまり詳しくないのですが、SQLにおいて末尾の空白の扱いは割と曖昧です。例えばSQL Serverにおいても[`SET
ANSI_PADDING`](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/set-ansi-
padding-transact-sql?view=sql-server-ver15)という設定が用意されており、`OFF`にすると末尾の空白を削ります。

[Microsoft Text Driver (*.txt; *.csv)](https://docs.microsoft.com/en-
us/sql/odbc/microsoft/microsoft-odbc-desktop-database-drivers?view=sql-server-
ver15)についてドキュメントを確認しましたが、この辺りを制御するオプションは用意されていませんでした。例えば[Schema.ini](https://docs.microsoft.com/en-
us/sql/odbc/microsoft/schema-ini-file-text-file-driver?view=sql-server-
ver15)を用意して、`char(2)`等と明示しても末尾の空白は削られることを確認しました。

結局、

  * 読み込んだ後で`char(2) not null`を満たすようにC#側で編集する
  * CsvHelperなど他のライブラリを使用する

しかなさそうです。


CC BY-SA 4.0
2021-06-29T22:59:16.600
77867
2021-06-29T22:59:16.600
4236
77761
answer