我在C#中创建了一个代码,它从多个文件夹中读取分隔的txt文件,解析数据,然后使用正确的值更新Microsoft SQL Server表。代码如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FileHelpers;
using System.Data.SqlClient;
using System.IO;
using System.Data;
namespace prototype_using_filehelpers
{
class ManagerReport
{
[DelimitedRecord("|")]
[IgnoreEmptyLines()]
[IgnoreFirst()]
public class ManagerReportNames
{
public int? MASTER_VALUE_ORDER;
public int? MASTER_VALUE;
public string RESORT;
public int? CS_HEADING_COUNT_MASTER;
public int? CS_FS_ARR_ROOMS_MASTER;
public int? CS_FS_DEP_ROOMS_MASTER;
public int? CS_FS_NO_ROOMS_MASTER;
public int? CS_FS_GUESTS_MASTER;
public int? CS_FS_TOTAL_REVENUE_MASTER;
public int? CS_FS_ROOM_REVENUE_MASTER;
public int? CS_FS_INVENTORY_ROOMS_MASTER;
public int? CF_FS_PERC_OCC_ROOMS_MASTER;
public int? CF_FS_AVG_ROOM_RATE_MASTER;
public int? LAST_YEAR_01;
public int? SUB_GRP_1_ORDER;
public string SUB_GRP_1;
public string DESCRIPTION;
public string AMOUNT_FORMAT_TYPE;
public string PRINT_LINE_AFTER_YN;
public int? HEADING_1_ORDER;
public int? HEADING_1;
[FieldOptional]
public string HEADING_2;
[FieldOptional]
[FieldConverter(ConverterKind.Decimal, ".")]
public decimal? SUM_AMOUNT;
[FieldOptional]
public decimal? FORMATTED_AMOUNT;
}
static void ProcessFilesCSVFiles(string copyPath, string destinationPath)
{
// first check if path exists
if (!Directory.Exists(copyPath))
// doesn't exist then exit, can't copy from something that doesn't exist
return;
var copyPathDirectory = new DirectoryInfo(copyPath);
// using the SearchOption.AllDirectories will search sub directories
var copyPathCSVFiles = copyPathDirectory.GetFiles("*.txt", SearchOption.AllDirectories);
// loops through directory looking for txt files
for (var i = 0; i < copyPathCSVFiles.Length; i++)
{
// get the file
var csvFile = copyPathCSVFiles[i];
//sets lines to the files full extention so it can then be called at a later time
string lines = csvFile.FullName;
// read the csv file line by line
FileHelperEngine engine = new FileHelperEngine(typeof(ManagerReportNames));
var records = engine.ReadFile(lines) as ManagerReportNames[];
foreach (var record in records)
{
Console.WriteLine(record.RESORT);
Console.WriteLine(record.FORMATTED_AMOUNT);
// SQL connection. Creates connection and command and inserts the values taken from the File Helper engine into the SQL table
SqlCommand cmd;
SqlConnection conn;
conn = new SqlConnection("Data Source=hureports01;Initial Catalog=hureports;Integrated Security=True");
conn.Open();
cmd = new SqlCommand("INSERT INTO test2 (property_id,val1) VALUES (@property_id,@val1)", conn);
cmd.Parameters.AddWithValue("@property_id", record.RESORT);
cmd.Parameters.AddWithValue("@val1", record.FORMATTED_AMOUNT);
cmd.ExecuteNonQuery();
}
// creates a variable that combines the the directory of the new folder with the file name
var destinationFilePath = Path.Combine(destinationPath, csvFile.Name);
// This loop prevents duplicates. If a file is already in the folder, it will delete the file already in there and move this one in.
// Shouldn't be an issue since each file will have a different name
if (File.Exists(destinationFilePath))
{
File.Delete(destinationFilePath);
}
// moves it to the new folder
csvFile.MoveTo(destinationFilePath);
}
}
static void Main(string[] args)
{
ProcessFilesCSVFiles(@"C:\Users\Documents", @"C:\Users\Documents\Complete");
}
}
}
代码有效,但我正在尝试实施新功能,而我不知道如何实现。目前,它正在使用两个值更新SQL Server:RESORT和FORMATTED_AMOUNT。 RESORT将进入表格列#34; property_id&#34;和FORMATTED_AMOUNT进入val1。在我的表中,我还添加了val2,val3和val4。 HEADING_2可以有三个不同的值,或者为null。我如何修复我的代码,以便当HEADING_2是第一个值时,相应的FORMATTED_AMOUNT将进入val1,当HEADING_2是第二个值时,相应的FORMATTED_AMOUNT将进入v2,当HEADING_2是第三个值时,相应的FORMATTED_AMOUNT将进入进入val3,最后当HEADING_2为空时,相应的FORMATTED_AMOUNT将进入val4
当前代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FileHelpers;
using System.Data.SqlClient;
using System.IO;
using System.Data;
namespace prototype_using_filehelpers
{
class ManagerReport
{
[DelimitedRecord("|")]
[IgnoreEmptyLines()]
[IgnoreFirst()]
[IgnoreLast(2)]
public class ManagerReportNames
{
public int? MASTER_VALUE_ORDER;
public int? MASTER_VALUE;
public string RESORT;
public int? CS_HEADING_COUNT_MASTER;
public int? CS_FS_ARR_ROOMS_MASTER;
public int? CS_FS_DEP_ROOMS_MASTER;
public int? CS_FS_NO_ROOMS_MASTER;
public int? CS_FS_GUESTS_MASTER;
public int? CS_FS_TOTAL_REVENUE_MASTER;
public int? CS_FS_ROOM_REVENUE_MASTER;
public int? CS_FS_INVENTORY_ROOMS_MASTER;
public int? CF_FS_PERC_OCC_ROOMS_MASTER;
public int? CF_FS_AVG_ROOM_RATE_MASTER;
public int? LAST_YEAR_01;
public int? SUB_GRP_1_ORDER;
public string SUB_GRP_1;
public string DESCRIPTION;
public string AMOUNT_FORMAT_TYPE;
public string PRINT_LINE_AFTER_YN;
public int? HEADING_1_ORDER;
public int? HEADING_1;
[FieldOptional]
public string HEADING_2;
[FieldOptional]
[FieldConverter(ConverterKind.Decimal, ".")]
public decimal? SUM_AMOUNT;
[FieldOptional]
public decimal? FORMATTED_AMOUNT;
}
static void ProcessFilesCSVFiles(string originalPath, string destinationPath)
{
// first check if path exists
if (!Directory.Exists(originalPath))
// doesn't exist then exit, can't copy from something that doesn't exist
return;
var copyPathDirectory = new DirectoryInfo(originalPath);
// using the SearchOption.AllDirectories will search sub directories
var copyPathCSVFiles = copyPathDirectory.GetFiles("*.txt", SearchOption.AllDirectories);
// loops through directory looking for txt files
for (var i = 0; i < copyPathCSVFiles.Length; i++)
{
// get the file
var csvFile = copyPathCSVFiles[i];
//sets lines to the files full extention so it can then be called at a later time
string lines = csvFile.FullName;
// read the csv file line by line
FileHelperEngine engine = new FileHelperEngine(typeof(ManagerReportNames));
var records = engine.ReadFile(lines) as ManagerReportNames[];
foreach (var record in records)
{
Console.WriteLine(record.RESORT);
Console.WriteLine(record.FORMATTED_AMOUNT);
// This allows us to split what column a row goes into based on whether it is a day month or year
string Heading = record.HEADING_2;
string Group = record.SUB_GRP_1;
string column;
if (Heading == "DAY" && Group == "OCC_PERC")
{
column = "Percent_Rooms_Occupied";
}
else if (Heading == "DAY" && Group == "OCC_PERC_WO_CH")
{
column = "Percent_Rooms_Occupied_minus_Comp_and_House";
}
else if (Heading == "DAY" && Group == "ADR_ROOM")
{
column = "ADR";
}
else if (Heading == "DAY" && Group == "ADR_ROOM_WO_CH")
{
column = "ADR_minus_Comp_and_House";
}
else if (Heading == "DAY" && Group == "ROOMREV_AVL_ROOMS_MINUS_OOO")
{
column = "Revenue_per_Available_Room_minus_OOO";
}
else if (Heading == "DAY" && Group == "TOTAL_REVENUE")
{
column = "Total_Revenue";
}
else if (Heading == "DAY" && Group == "ROOM_REVENUE")
{
column = "Room_Revenue";
}
else if (Heading == "DAY" && Group == "FOOD_BEV_REVENUE")
{
column = "Food_And_Beverage_Revenue";
}
else if (Heading == "DAY" && Group == "OTHER_REVENUE")
{
column = "Other_Revenue";
}
else if (Heading == "DAY" && Group == "PHYSICAL_ROOMS")
{
column = "Total_Rooms_in_Hotel";
}
else if (Heading == "DAY" && Group == "OCC_ROOMS")
{
column = "Rooms_Occupied";
}
else if (Heading == "DAY" && Group == "OCC_MINUS_COMP_HU")
{
column = "Rooms_Occupied_minus_Comp_and_House_Use";
}
else if (Heading == "DAY" && Group == "COMP_ROOMS")
{
column = "Complimentary_Rooms";
}
else
{
continue;
}
// SQL connection. Creates connection and command and inserts the values taken from the File Helper engine into the SQL table
SqlCommand cmd;
SqlConnection conn;
conn = new SqlConnection("Data Source=hureports01;Initial Catalog=hureports;Integrated Security=True");
conn.Open();
//var sqlCommand2 = string.Format(@"IF EXISTS (SELECT * FROM[HEWreport] WHERE Property_ID = @Property_ID) INSERT INTO[HEWreport] (Property_ID, < ColumnName >) VALUES(@Property_ID, @val");
var sqlCommand = string.Format(@"MERGE [HEWreport] AS target USING (select @Property_ID as Property_ID, @val as {0}) AS source ON (target.Property_ID = source.Property_ID) WHEN MATCHED THEN UPDATE SET {0}= source.{0}
WHEN NOT MATCHED THEN INSERT (Property_ID, {0}) VALUES (source.Property_ID, source.{0});", column);
cmd = new SqlCommand(sqlCommand, conn);
cmd.Parameters.AddWithValue("@Property_ID", record.RESORT);
cmd.Parameters.AddWithValue("@val", record.FORMATTED_AMOUNT);
cmd.ExecuteNonQuery();
conn.Close();
}
// creates a variable that combines the the directory of the new folder with the file name
var destinationFilePath = Path.Combine(destinationPath, csvFile.Name);
// This loop prevents duplicates. If a file is already in the folder, it will delete the file already in there and move this one in.
// Shouldn't be an issue since each file will have a different name
if (File.Exists(destinationFilePath))
{
File.Delete(destinationFilePath);
}
// moves it to the new folder
csvFile.MoveTo(destinationFilePath);
}
}
static void Main(string[] args)
{
ProcessFilesCSVFiles(@"C:\Users\Documents\Hotels", @"C:\Users\Documents\Completed Hotels");
}
}
}
正如你所看到的,我完全改变了我想做的事情,但它的概念相同。而不是列定义为val1或val2,我还需要比HEADING_2中的更多,我还需要SUB_GRP_1。我也尝试过使用参数,因为我还被告知AddWithValue()可能导致问题,但仍然没有工作
答案 0 :(得分:0)
假设你有一个将HEADING_2映射到列名的功能,就像这个
一样 document.getElementById('AdminLinks')
您可以按以下方式更改代码:
var columnName = GetColumnNameFromHEADING_2(HEADING_2_value);
如果要按照注释中的描述组合行,请使用merge语句:
var sqlCommand = string.Format("INSERT INTO test2 (property_id, {0}) VALUES (@property_id,@val)", columnName);
cmd = new SqlCommand(sqlCommand, conn);
cmd.Parameters.AddWithValue("@property_id", record.RESORT);
cmd.Parameters.AddWithValue("@val", record.FORMATTED_AMOUNT);