繁体   English   中英

C#将数据库提取到SQL Server数据表中

[英]c# fetching database into SQL Server datatable

我的这段代码有问题...我对发生的事情一无所知...

在Visual Studio中运行此代码时,出现错误消息:

System.InvalidCastException:'无法将对象从DBNull强制转换为其他类型。

这是代码:

conn.Open();

SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'", conn);

SqlDataAdapter da = new SqlDataAdapter("Declare @startdate smalldatetime declare @enddate smalldatetime set @startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set @enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, @startdate+2, @enddate)as timepassedd", conn);

DataTable dt = new DataTable();
da.Fill(dt);

foreach (DataRow DR in dt.Rows)
{
    int date;
    date = Convert.ToInt32(DR["timepassedd"]);

    if (date > 0)
    {
        com = new SqlCommand("DELETE lend WHERE client_name ='"+comboBox1.Text+"'" +
                             "UPDATE book_list set book_stock = book_stock  1 WHERE book_name ='" + comboBox1.Text + "'",conn);
        com.ExecuteNonQuery();

        MessageBox.Show("You Returned the book " + date + " Days Late!" +
                            "please pay the fee to the front desk");

        UserPanel u = new UserPanel();
        u.Show();

        this.Hide();
    }
    else if (date <= 0)
    {
        com = new SqlCommand("DELETE lend WHERE client_name ='" + comboBox1.Text + "'" +
                             "UPDATE book_list set book_stock = book_stock  1 WHERE book_name ='" + comboBox1.Text + "'", conn);
        com.ExecuteNonQuery();

        MessageBox.Show("You returned the book " + date + " Days Late!" +
                            "please pay the fee to the front desk");

        UserPanel u = new UserPanel();
        u.Show();

        this.Hide();
    }
}

conn.Close();

提前致谢

答案下面的运行代码将很明显:

                string sql1 = "update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'";
                Console.WriteLine(sql1);
                Console.ReadLine();
                SqlCommand com = new SqlCommand(sql1, conn);
                string sql2 = "Declare @startdate smalldatetime declare @enddate smalldatetime set @startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set @enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, @startdate+2, @enddate)as timepassedd"
                Console.ReadLine();
                SqlDataAdapter da = new SqlDataAdapter(sql2, conn);
        conn.Open();
        SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'", conn);
        SqlDataAdapter da = new SqlDataAdapter("Declare @startdate smalldatetime declare @enddate smalldatetime set @startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set @enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, @startdate+2, @enddate)as timepassedd", conn);
        DataSet ds = new DataSet();
        da.Fill(ds);
        if(ds.Tables.Count == 1)
        {
            if(ds.Tables[0].Rows.Count > 0)
            {
                foreach(DataRow dr in ds.Tables[0].Rows)
                {
                    if(dr.ItemArray.Length > 0)
                    {
                        if(dr["timepassedd"] != DBNull.Value)
                        {
                            int date;
                            date = Convert.ToInt32(Dr["timepassedd"]);
                            if (date > 0)
                            {
                                com = new SqlCommand("delete lend where client_name ='" + comboBox1.Text + "'" +
                                    "UPDATE book_list set book_stock = book_stock  1 WHERE book_name ='" + comboBox1.Text + "'", conn);
                                com.ExecuteNonQuery();
                                MessageBox.Show("You Returned the book " + date + " Days Late!" +
                                    "please pay the fee to the front desk");
                                UserPanel u = new UserPanel();
                                u.Show();
                                this.Hide();
                            }
                            else if (date <= 0)
                            {
                                com = new SqlCommand("delete lend where client_name ='" + comboBox1.Text + "'" +
                                    "UPDATE book_list set book_stock = book_stock  1 WHERE book_name ='" + comboBox1.Text + "'", conn);
                                com.ExecuteNonQuery();
                                MessageBox.Show("You Returned the book " + date + " Days Late!" +
                                    "please pay the fee to the front desk");
                                UserPanel u = new UserPanel();
                                u.Show();
                                this.Hide();
                            }
                        }
                    }
                }
            }
        }
        conn.Close();

您应该检查DBNull值,如果该列在数据库中可以为空,则将返回DBNull.Value 因此,在处理此列之前,应检查此列是否具有此类值
同样,您不应该接受来自用户输入的值并将其直接注入SQL查询中! ADO.Net 可以在SqlCommand类的Parameters属性中找到名为Sql Parameters东西。 您应该使用此属性将用户的值作为参数添加到查询中
例如,可以这样添加客户端名称:

    com.Parameters.Add(new SqlParameter("client_name", comboBox1.Text));

现在,您告诉Sql Command,该值实际上是在SqlParameters集合中呈现的,如下所示:

SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='@client_name'", conn);

看看这个问题, 为什么我们总是喜欢在SQL语句中使用参数?
这是Parameters属性的MSDN参考

set @startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "')
set @enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "')

a)如果comboBox1.Text曾经包含'字符,则容易发生意外行为

b)如果没有与组合框中所选内容匹配的记录,则两者都会导致@startdate或@enddate为NULL,然后为'@datepassedd'生成NULL值,因此在尝试转换为int时出错。

c)您不需要两次查询数据库,您只需执行

select DATEDIFF(DAY, date_lended+2, date_back) as timepassedd FROM dbo.lend where client_name = @clientName

(然后可以将@clientName添加为参数)

在这种情况下,如果没有记录与名称匹配,将不会返回任何行。 顺便说一句,您永远不需要使用DataTable并遍历记录,因为现在的查询只返回一行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM