【问题标题】:SQL Server C# can't insert in to the databaseSQL Server C# 无法插入数据库
【发布时间】:2016-05-10 19:35:07
【问题描述】:

问题:

“System.Data.SqlClient.SqlException”类型的异常发生在 System.Data.dll 但未在用户代码中处理

附加信息:
参数化查询(@name nvarchar(7), @height float, @heightscale nvarchar(5), @weigh 需要参数@monthDis,但未提供该参数

我的代码:

public partial class Step3 : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        SqlConnection c;

        string str = "Data Source =(LocalDB)\\MSSQLLocalDB;";
        str += "AttachDbFilename=|DataDirectory|\\DinoData.mdf;";
        str += "Integrated Security= True";

        c = new SqlConnection(str);

        if (Page.IsValid == true)
        {
            Session["yourlocation"] = ddlcountry.SelectedItem.Text;
            Session["dayborn"] = DDLborn.SelectedItem.Text;
            Session["monthborn"] = ddlmonthborn.SelectedItem.Text;
            Session["yearborn"] = txtyar.Text;
            Session["yourEmail"] = txtemail.Text;
            Session["Gender"] = rbgendere.SelectedItem.Text;
            Session["YourName"] = txtName.Text;
            Session["YourLastName"] = txtLName.Text;

            SqlCommand NewUser = new SqlCommand("INSERT INTO [DinoTable] VALUES(@name, @height, @heightscale, @weight, @weightscale, @diet, @status, @locationDis, @dayDis, @monthDis, @yearDis, @yourlocation, @dayborn, @monthborn, @yearborn, @Gender, @yourEmail, @yoname, @lastname);", c);
            NewUser.Connection = c;

            NewUser.Parameters.AddWithValue("@name", (string) Session["Name"]);
            NewUser.Parameters.AddWithValue("@height", Convert.ToDouble(Session["Height"]));
            NewUser.Parameters.AddWithValue("@heightscale", (string)Session["HeightScale"]);
            NewUser.Parameters.AddWithValue("@weight", Convert.ToDouble(Session["Weight"]));
            NewUser.Parameters.AddWithValue("@weightscale", (string)Session["weightscale"]);
            NewUser.Parameters.AddWithValue("@diet", (string)Session["diet"]);
            NewUser.Parameters.AddWithValue("@status", (string)Session["status"]);
            NewUser.Parameters.AddWithValue("@locationDis", (string)Session["locationDis"]);
            NewUser.Parameters.AddWithValue("@dayDis", Convert.ToInt32(Session["dayDis"]));
            NewUser.Parameters.AddWithValue("@monthDis", (string)(Session["monthDis"]));
            NewUser.Parameters.AddWithValue("@yearDis", Convert.ToInt32(Session["yearDis"]));
            NewUser.Parameters.AddWithValue("@yourlocation", (string)Session["yourlocation"]);
            NewUser.Parameters.AddWithValue("@dayborn", Convert.ToInt32(Session["dayborn"]));
            NewUser.Parameters.AddWithValue("@monthborn", (string)(Session["monthborn"]));
            NewUser.Parameters.AddWithValue("@yearborn", Convert.ToInt32(Session["yearborn"]));
            NewUser.Parameters.AddWithValue("@Gender", (string)Session["Gender"]);
            NewUser.Parameters.AddWithValue("@yourEmail", (string)Session["yourEmail"]);
            NewUser.Parameters.AddWithValue("@yoname", (string)Session["YourName"]);
            NewUser.Parameters.AddWithValue("@lastname", (string)Session["YourLastName"]);
            NewUser.Parameters.AddWithValue("@MoneyinMilions", 3);

            c.Open();
            NewUser.ExecuteNonQuery();
            c.Close();

            Response.Redirect("finish%20new.aspx", true);
        }
    }
}

感谢大家的帮助!

【问题讨论】:

  • 您应该查看Can we stop using AddWithValue() already? 并停止使用.AddWithValue() - 它可能会导致意想不到和令人惊讶的结果...
  • 在查询中找不到参数@MoneyinMilions!
  • 你能显示表 [DinoTable] 的架构吗?
  • 同样不要在INSERT语句中省略列名;我们不知道[DinoTable] 包含什么或它的列的顺序。
  • 我不能长时间发表评论

标签: c# sql-server


【解决方案1】:

您的 SQL 查询中缺少 @MoneyinMillions。

 SqlCommand NewUser = new SqlCommand("INSERT INTO [DinoTable] VALUES(@name, 
 @height, @heightscale, @weight, @weightscale, @diet, @status, @locationDis, 
 @dayDis, @monthDis, @yearDis, @yourlocation, @dayborn, @monthborn, @yearborn, 
 @Gender, @yourEmail, @yoname, @lastname, @MoneyinMillions);", c);

【讨论】:

    【解决方案2】:

    我很确定您的问题是您的查询。

     SqlCommand NewUser = new SqlCommand("INSERT INTO [DinoTable] VALUES(@name, @height, @heightscale, @weight, @weightscale, @diet, @status, @locationDis, @dayDis, @monthDis, @yearDis, @yourlocation, @dayborn, @monthborn, @yearborn, @Gender, @yourEmail, @yoname, @lastname);", c);
    

    您正在将参数添加到查询中,但它很可能为空。 NewUser.Parameters.AddWithValue("@monthDis", (string)(Session["monthDis"]));

    您需要检查会话变量是否为空,然后再按照@DevTony 的建议进行传递。

     protected void Button1_Click(object sender, EventArgs e)
        {
            //when using sql connection objects, be sure to enclose them in a using block to properly dispose of resources.
            string connectionString =
                @"Data Source =(LocalDB)\MSSQLLocalDB; AttachDbFilename=|DataDirectory|\DinoData.mdf;Integrated Security= True;";
            //if you want to use SQL Server security, set Integrated Security to FALSE.  TRUE means use Windows Integrated Security.
            string queryString =
                "INSERT INTO [DinoTable] VALUES(@name, @height, @heightscale, @weight, @weightscale, @diet, @status, @locationDis, @dayDis, @monthDis, @yearDis, @yourlocation, @dayborn, @monthborn, @yearborn, @Gender, @yourEmail, @yoname, @lastname, @MoneyinMilions);";
    
            //normally, you'd print an error on the form to tell the user why their data was wrong.
            if (Session["yourLocation"] != null)
                Session["yourlocation"] = ddlcountry.SelectedItem.Text;
            else
            {
                return;
            }
            if (Session["dayborn"] != null)
                Session["dayborn"] = ddlBorn.SelectedItem.Text;
            else
            {
                return;
            }
            if (Session["monthborn"] != null)
                Session["monthborn"] = ddlmonthborn.SelectedItem.Text;
            else
            {
                return;
            }
            if (Session["yearborn"] != null)
                Session["yearborn"] = txtyar.Text;
            else
            {
                return;
            }
            if (Session["yourEmail"] != null)
                Session["yourEmail"] = txtemail.Text;
            else
            {
                return;
            }
            if (Session["Gender"] != null)
                Session["Gender"] = rbGender.SelectedItem.Text;
            else
            {
                return;
            }
            if (Session["YourName"] != null)
                Session["YourName"] = txtName.Text;
            else
            {
                return;
            }
            if (Session["YourLastName"] != null)
                Session["YourLastName"] = txtLName.Text;
            else
            {
                return;
            }
    
    
            if (Page.IsValid == true)
            {
                using (SqlConnection c = new SqlConnection(connectionString))
                {
                    //not sure why you are just using session objects.  If you've disabled session for the controls,
                    //then it makes sense.  Otherwise just use the dropdown's text value directly.                    
    
                    using (SqlCommand newUser = new SqlCommand(queryString, c))
                    {
                        newUser.Parameters.AddWithValue("@name", (string)Session["Name"]);
                        newUser.Parameters.AddWithValue("@height", Convert.ToDouble(Session["Height"]));
                        newUser.Parameters.AddWithValue("@heightscale", (string)Session["HeightScale"]);
                        newUser.Parameters.AddWithValue("@weight", Convert.ToDouble(Session["Weight"]));
                        newUser.Parameters.AddWithValue("@weightscale", (string)Session["weightscale"]);
                        newUser.Parameters.AddWithValue("@diet", (string)Session["diet"]);
                        newUser.Parameters.AddWithValue("@status", (string)Session["status"]);
                        newUser.Parameters.AddWithValue("@locationDis", (string)Session["locationDis"]);
                        newUser.Parameters.AddWithValue("@dayDis", Convert.ToInt32(Session["dayDis"]));
                        newUser.Parameters.AddWithValue("@monthDis", (string)(Session["monthDis"]));
                        newUser.Parameters.AddWithValue("@yearDis", Convert.ToInt32(Session["yearDis"]));
                        newUser.Parameters.AddWithValue("@yourlocation", (string)Session["yourlocation"]);
                        newUser.Parameters.AddWithValue("@dayborn", Convert.ToInt32(Session["dayborn"]));
                        newUser.Parameters.AddWithValue("@monthborn", (string)(Session["monthborn"]));
                        newUser.Parameters.AddWithValue("@yearborn", Convert.ToInt32(Session["yearborn"]));
                        newUser.Parameters.AddWithValue("@Gender", (string)Session["Gender"]);
                        newUser.Parameters.AddWithValue("@yourEmail", (string)Session["yourEmail"]);
                        newUser.Parameters.AddWithValue("@yoname", (string)Session["YourName"]);
                        newUser.Parameters.AddWithValue("@lastname", (string)Session["YourLastName"]);
                        newUser.Parameters.AddWithValue("@MoneyinMilions", 3);
    
                        c.Open();
                        newUser.ExecuteNonQuery(); //if you are not returning a result set, this is what you use.  Use ExecuteQuery() if you want to return data from the DB.
                        c.Close();
                    }
                }
                Response.Redirect("finish%20new.aspx", true);
            }
        }
    

    这是一个学习如何使用 SQL 连接的资源。

    http://www.codeproject.com/Articles/823854/How-to-connect-SQL-Database-to-your-Csharp-program

    【讨论】:

    • 我不得不去采石场赚到百万美元
    • 我对此很陌生,所以你能解释一下我之前应该做什么,为什么??
    • 我强烈建议您尝试在添加了所有参数的 SSMS(Sql Server Management Studio)中运行查询,然后朝着 VS 前进。我还建议您使用存储过程 - 这样,如果您在不同的地方重用此查询,如果问题是缺少参数或其他问题,您可以缩小范围。我将编辑我的答案,以便您可以看到应该做什么以及资源,以便您了解有关这些内容的更多信息。
    • 他们不在同一个页面,所以它不会以这种方式工作
    • 不过我还是会试试的
    【解决方案3】:

    未分配的会话变量在查询时返回为null。当通过AddWithValue 作为参数传递时,它会产生您所看到的错误。

    如果不需要数据库中的值(它是一个可为空的列),那么您可以使用 C# 合并运算符测试 null 并替换为 DBNull.Value

    NewUser.Parameters.AddWithValue("@monthDis", Session["monthDis"] ?? DBNull.Value);
    

    或者,如果需要该值(NOT NULL 列),那么您应该提供一个默认值(或抛出异常):

    NewUser.Parameters.AddWithValue("@monthDis", Session["monthDis"] ?? "");
    

    我对构建 SQL 参数的代码部分进行了微调(包括在 Namenull 时抛出异常,因为那是主键):

    //exit function if any required values are not specified in the Session
    if (Session["Name"] == null)
    {
        throw new Exception("Name is a required but not specified");
    }
    
    using (SqlCommand newUser = new SqlCommand(queryString, c))
    {
        newUser.Parameters.AddWithValue("@name", Session["Name"]);
        newUser.Parameters.AddWithValue("@height", Convert.ToDouble(Session["Height"]));
        newUser.Parameters.AddWithValue("@heightscale", Session["HeightScale"] ?? "");
        newUser.Parameters.AddWithValue("@weight", Convert.ToDouble(Session["Weight"]));
        newUser.Parameters.AddWithValue("@weightscale", Session["weightscale"] ?? "");
        newUser.Parameters.AddWithValue("@diet", Session["diet"] ?? "");
        newUser.Parameters.AddWithValue("@status", Session["status"] ?? "");
        newUser.Parameters.AddWithValue("@locationDis", Session["locationDis"] ?? "");
        newUser.Parameters.AddWithValue("@dayDis", Convert.ToInt32(Session["dayDis"]));
        newUser.Parameters.AddWithValue("@monthDis", Session["monthDis"] ?? "");
        newUser.Parameters.AddWithValue("@yearDis", Convert.ToInt32(Session["yearDis"]));
        newUser.Parameters.AddWithValue("@yourlocation", Session["yourlocation"] ?? "");
        newUser.Parameters.AddWithValue("@dayborn", Convert.ToInt32(Session["dayborn"]));
        newUser.Parameters.AddWithValue("@monthborn", Session["monthborn"] ?? "");
        newUser.Parameters.AddWithValue("@yearborn", Convert.ToInt32(Session["yearborn"]));
        newUser.Parameters.AddWithValue("@Gender", Session["Gender"] ?? "");
        newUser.Parameters.AddWithValue("@yourEmail", Session["yourEmail"] ?? "");
        newUser.Parameters.AddWithValue("@yoname", Session["YourName"] ?? "");
        newUser.Parameters.AddWithValue("@lastname", Session["YourLastName"] ?? "");
        newUser.Parameters.AddWithValue("@MoneyinMilions", 3);
    
        c.Open();
        newUser.ExecuteNonQuery(); //if you are not returning a result set, this is what you use.  Use ExecuteQuery() if you want to return data from the DB.
        c.Close();
    }
    

    此外,在插入时,必须将所有未在数据库中配置默认​​值的表的必填字段指定为查询字符串中的参数。在插入过程中显式列出列名也是一个好习惯:

    string queryString =
            "INSERT INTO [DinoTable] (DinoName, DinoHeight, Heightskale, DinoWeight, Weightskale, diet, Status, LocationDiscovery, DayDiscovery, monthDiscovery, yearDiscovery, YourLocation, DayBorn, monthBorn, YearBorn, YourGender, YourEmail, YourName, YourLastName, MoneyinMilions) VALUES(@name, @height, @heightscale, @weight, @weightscale, @diet, @status, @locationDis, @dayDis, @monthDis, @yearDis, @yourlocation, @dayborn, @monthborn, @yearborn, @Gender, @yourEmail, @yoname, @lastname, @MoneyinMilions);";
    

    【讨论】:

    • 感谢您发布表格结构。我没有意识到这些字段是不可为空的。为了完整起见,我已经修正了我的答案,并包含了 bjones 和 Richard_D 的建议,希望其中有一些有用的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多