using KssSmaPlaLib.Commons; using KssSmaPlaLib.IO.Database; using KssSmaPlaLib.IO.File; using Org.BouncyCastle.Asn1.X509; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace KssSmaPlaLib.Exchange { public static class CsvDbSyncUxer { private const string INI_KEY_INSERT_PROCESSING_MODE = "InsertProcessingMode"; private const string INI_VALUE_INSERT_PROCESSING_MODE_BULK = "Bulk"; private const string INI_VALUE_INSERT_PROCESSING_MODE_ROW_BY_ROW = "RowByRow"; private const string INI_KEY_SQL_NAME_INSERT_BULK = "SqlNameInsertBulk"; public static bool InsertDbFromCsvFiles( Dictionary iniDic, DbUxer con, string csvFilePath, string dupCheckSql, string insertSqlName, out string resultMessage, EncodingUxer.EncodingType encodingType = EncodingUxer.EncodingType.Utf8WithoutBom) { var messageForMe = string.Empty; resultMessage = string.Empty; var mode = DictionaryUxer.GetValueOrDefault( iniDic, INI_KEY_INSERT_PROCESSING_MODE, INI_VALUE_INSERT_PROCESSING_MODE_ROW_BY_ROW); //if (string.IsNullOrEmpty(mode)) //{ // resultMessage = $"挿入モードが設定されていません。[キー:{INI_KEY_INSERT_PROCESSING_MODE}]"; // return false; //} string[] validValues = { INI_VALUE_INSERT_PROCESSING_MODE_BULK, INI_VALUE_INSERT_PROCESSING_MODE_ROW_BY_ROW }; mode = mode.Trim(); if (!validValues.Contains(mode, StringComparer.OrdinalIgnoreCase)) { resultMessage = $"挿入モードの値が不正です。[{INI_KEY_INSERT_PROCESSING_MODE}:{mode}]"; return false; } if (mode.ToUpper() == INI_VALUE_INSERT_PROCESSING_MODE_ROW_BY_ROW.ToUpper()) { // 1行ずつ挿入(従来方式) // CSV読み込み if (!CsvUxer.ImportFromCsv(csvFilePath, out var rs, out messageForMe, encodingType)) { resultMessage = messageForMe; return false; } LoggerUxer.Info($"[CSV件数:{rs.Count}]"); if (string.IsNullOrEmpty(dupCheckSql)) { LoggerUxer.Info($"重複チェックSQLが未指定のため重複チェックは行いません。"); } else { LoggerUxer.Info($"重複チェックを行います。[SQLファイル:{dupCheckSql}]"); } foreach (var rec in rs) { var recObj = rec.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value); if (!string.IsNullOrEmpty(dupCheckSql)) { // 重複チェック if (!con.ExecuteQuery(dupCheckSql, recObj, out var dupRs, out messageForMe)) { resultMessage = "重複チェックエラー:" + messageForMe; return false; } if (dupRs.Count != 1) { resultMessage = $"重複チェックで取得件数エラーです。[取得件数:{dupRs.Count}]"; return false; } // ↓COUNT(*)の結果型はintにあらず(ポスグレの場合long)ゆえに文字列化してint化する if (!int.TryParse(dupRs[0].Values.ElementAt(0).ToString(), out var intCnt)) { resultMessage = $"重複チェックで取得値(件数)が数値ではありません。[取得値:{dupRs[0].Values.ElementAt(0)}]"; return false; } // 重複レコードありの場合、飛ばす if (intCnt > 0) { LoggerUxer.Info($"重複レコードのため、飛ばします。[該当件数:{intCnt}]"); continue; } LoggerUxer.Info($"重複チェックにて重複レコードは見つかりませんでした。"); } // DB挿入 if (!string.IsNullOrEmpty(insertSqlName)) { LoggerUxer.Info($"[DB挿入SQL名:{insertSqlName}]"); if (!con.ExecuteNonQuery(insertSqlName, recObj, out var resultCount, out messageForMe)) { resultMessage = messageForMe; return false; } LoggerUxer.Info($"[DB挿入件数:{resultCount}]"); } else { LoggerUxer.Info($"DB挿入SQL名が未指定のためDB挿入は行いません。"); } } } else { // バルク挿入 LoggerUxer.Info($"バルク挿入が指定されました。"); insertSqlName = DictionaryUxer.GetValueOrDefault( iniDic, INI_KEY_SQL_NAME_INSERT_BULK, string.Empty); if (string.IsNullOrEmpty(insertSqlName)) { resultMessage = $"バルク挿入SQLファイル名が指定されていません。[キー:{INI_KEY_SQL_NAME_INSERT_BULK}]"; return false; } LoggerUxer.Info($"[DBバルク挿入SQL名:{insertSqlName}]"); if (!con.BeginTextImport(insertSqlName, csvFilePath, out var resultCount, out messageForMe)) { resultMessage = messageForMe; return false; } LoggerUxer.Info($"[DBバルク挿入件数:{resultCount}]"); } return true; } } }