未在c#SQL命令中设置值

时间:2016-05-26 17:57:55

标签: c# sql-server visual-studio

我编写了一个代码,该代码将读取txt文件并解析数据并将正确的数字分配到SQL表的正确列中。我遇到的问题是我实现了一个Merge,以便来自txt文件中不同行的数据将显示在不同的列中,但SQL表中的行相同。但是,我现在遇到的问题是我的变量没有设置,但是在我实现合并之前。这是我的代码:

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 and what SUB_GRP_1 it is
    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
    {
        column = "";
    }




    // 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 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();
}

这就是我不断得到的错误:

  

System.Data.dll中出现未处理的“System.Data.SqlClient.SqlException”类型异常

     

附加信息:参数化查询'(@Property_ID nvarchar(5),@ val nvarchar(4000))MERGE [HEWreport]'需要参数'@val',这是未提供的。

我知道这与我的行中的错误有关

cmd.Parameters.AddWithValue("@val", record.FORMATTED_AMOUNT);

但我不知道如何解决它

2 个答案:

答案 0 :(得分:0)

您是否附加了SQL事件探查器?什么是发送到SQL Server的查询?

代码(一般来说)看起来是正确的 错误消息暗示未提供“@val”,但您显示的代码正在添加它。可能是record.FORMATTED_AMOUNT为null或者有一些其他问题导致参数不被添加,但是这应该抛出一个C#异常。

您也可能正在运行旧代码,因此您复制的内容与正在运行的代码不同。

如果SQL事件探查器没有为您提供所需的信息,请尝试静态指定C#中的值,看看会发生什么。

var sqlCommand = @"MERGE [HEWreport] AS target USING (select @Property_ID as Property_ID, @val as ColumnName) AS source ON (target.Property_ID = source.Property_ID) WHEN MATCHED THEN UPDATE SET ColumnName = source.ColumnName
                                WHEN NOT MATCHED THEN INSERT (Property_ID, ColumnName) VALUES (source.Property_ID, source.ColumnName);";
cmd = new SqlCommand(sqlCommand, conn);
cmd.Parameters.AddWithValue("@Property_ID", "215");
cmd.Parameters.AddWithValue("@val", "17");
cmd.ExecuteNonQuery();

其他评论:

对于insert语句(没有UPDATE或DELETE),MERGE是过度的。而是使用类似的东西:

IF EXISTS (SELECT * FROM [HEWreport] WHERE Property_ID = @Property_ID)
    INSERT INTO [HEWreport] (Property_ID, <ColumnName>) VALUES (@Property_ID, @val);

如评论中所示,不建议使用cmd.Parameters.AddWithValue。而是创建一个SqlParmeter

cmd.Parameters.Add(new SqlParameter("@Property_ID", SqlDbType.Int) { Value = record.RESORT});
cmd.Parameters.Add(new SqlParameter("@val", SqlDbType.NVarChar, 250) { Value = record.FORMATTED_AMOUNT});

文档:
SqlParameter Constructor (String, SqlDbType)
SqlParameter Constructor (String, SqlDbType, Int32)

答案 1 :(得分:0)

当record.RESORT和/或record.FORMATTED_AMOUNT为空时会发生这种情况。有关类似问题,请参阅here