読者です 読者をやめる 読者になる 読者になる

【SSIS】NULLの値を一括置換する

こんなデータがあったとします。

hoge,piyo,fuga,hogehoge,piyopiyo,fugafuga,foo,bar
1,,1,1,1,,1,
,1,,1,,1,1,1
1,,,1,,,,1
,,,,,,,
1,,1,,1,1,,
1,,1,,1,,1,1
1,,1,,1,1,1,1
1,1,1,1,1,1,1,1

このデータのNULLの部分を全部0にしたい、となると、派生列でえっちらおっちら、なんて方法もありますが、項目数が多いと正直だるいです。

INPUTがDBなら正規表現ISNULL関数でもつけてやれば済むんですが、フラットファイルなんかだとそうもいきません。

そんな時はリフレクションでもして一気にやってしまおうよってお話です。

コード

public override void 入力0_ProcessInputRow(入力0Buffer Row)
{
    var propArray = Row.GetType().GetProperties();

    do
    {
        var dic = new Dictionary<string, bool>();

        foreach (var prop in propArray
                            .Where(x => x.Name.Contains("_IsNull"))
                            .Select(x => new { Name = x.Name.Replace("_IsNull", ""), Value = (bool)x.GetValue(Row, null) }))
        {
            dic.Add(prop.Name, prop.Value);
        }

        foreach (var prop in propArray
                            .Where(x => !x.Name.Contains("_IsNull"))
                            .Where(x => dic[x.Name]))
        {
            prop.SetValue(Row, "0", null);
        }

    } while (Row.NextRow());
}

いっつも思うんですが、NULLかどうかを判断するためには全く別のプロパティを見ないといけないのが本当にクソです。

注意する点は二つ。一つは入力列の設定ですべてのカラムを「ReadWrite」にすること。もう一つはそれぞれのカラムの型が違う場合は必ずSetValueの前にPropertyTypeを取得し、分岐させること。今回は全部Stringだとわかってるので割愛しています。

結果

hoge,piyo,fuga,hogehoge,piyopiyo,fugafuga,foo,bar
1,0,1,1,1,0,1,0
0,1,0,1,0,1,1,1
1,0,0,1,0,0,0,1
0,0,0,0,0,0,0,0
1,0,1,0,1,1,0,0
1,0,1,0,1,0,1,1
1,0,1,0,1,1,1,1
1,1,1,1,1,1,1,1