簡體   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