查询

时间:2016-05-05 04:13:55

标签: c# wpf ms-access datatable oledb

首先,我想指出,我知道要避免在SQL查询中直接使用TextBox或DatePicker中的字符串,如下面的代码所示。在我弄清楚如何完成这项工作后,我打算解决所有这些问题,但为了简单起见,在最初编码和测试时,我现在正在使用它。我指出这一点是因为我在Google上发现的所有内容都指出了这一点,但似乎并没有给出真正问题的实际答案。 :)话虽如此,这里... ...

我有一个Access 2010数据库(.accdb),我需要从中读取数据,以便在WPF中填充多个TextBox。无论我如何格式化查询中的日期,我都会得到一种类型的异常。我一直在使用的代码是:

    public void UpdateEarlyStageData(string filePath, string query)
    {
        List<string> departments = new List<string>();

        string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=" + filePath + ";" +
            @"User Id=;Password=;";

        using (OleDbConnection connection = new OleDbConnection(connectionString))
        {
            try
            {
                connection.Open();

                using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, connection))
                {
                    System.Data.DataTable table = new System.Data.DataTable();
                    adapter.Fill(table);

                    massCellRecords.Text = table.Rows[0]["MASSCellRecords"].ToString();
                    massCellDials.Text = table.Rows[0]["MASSCellDials"].ToString();
                    massCellSaturation.Text = table.Rows[0]["MASSCellSaturation"].ToString();
                    massCellPercentTotal.Text = table.Rows[0]["MASSCellPercentVolume"].ToString();
                    massCellPercentWorked.Text = table.Rows[0]["MASSCellPassPenetration"].ToString();
                    massCellPassPercent.Text = table.Rows[0]["MASSCellTotalPassPenFactor"].ToString();

                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

    }

    private void recordDateES_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
    {            
        string filePath = "C:\\Dialer Team Back-End Database\\DialerTeam_be.accdb";
        DateTime targetDate = DateTime.Parse(recordDateES.ToString());
        //string queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #" + DateTime.Today.ToShortDateString() + "#";
        string queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #" + targetDate.ToShortDateString() + "#";
        //queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #" + targetDate + "#";
        queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #05//02//2016#";

        UpdateEarlyStageData(filePath, queryString);
    }

我见过的例外情况是:

InvalidOperationException:提供程序无法确定Double值。

当我将查询格式化为queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #05/02/2016#";时会发生这种情况。我假设这里发生的事情是它试图将05除以02,结果是2016年。

OleDbException:查询表达式中日期的语法错误&#39; CallDate =#05 // 02 // 2016&#39;

当我将查询格式化为queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #05//02//2016#";时会发生这种情况。我不知道为什么会出现这种情况,因为我有其他使用此格式的查询,唯一的区别是他们没有使用DataTable而只是直接OleDbDataReader。< / p>

上面代码中的每个注释掉的行反映了各种尝试使其工作,但它们都不起作用......请帮忙!

更新 我还没有找到解决方案或答案,但我确实有工作代码来完成同样的事情。我没有使用DataTable,而是直接使用OleDbConnection。由于这不是解决问题的真正解决方案,因此我不认为这本身就是一个答案,所以我只是要粘贴下面的代码,以便任何有类似问题的人在将来可以参考这个。

    private void saveData_Click(object sender, RoutedEventArgs e)
    {
        if (departmentSelector.SelectedIndex == 2)
        {
            string query = "";
            string filePath = "C:\\Dialer Team Back-End Database\\DialerTeam_be.accdb";
            DateTime targetDate = DateTime.Parse(recordDateES.ToString());

            string massCellString = "MASSCellRecords = @massCellRecords, MASSCellDials = @massCellDials, MASSCellSaturation = @massCellSaturation," +
                " MASSCellPercentVolume = @massCellPercentVolume, MASSCellPassPenetration = @massCellPassPenetration, MASSCellTotalPassPenFactor =  @massCellTotalPassPenFactor";
            string miCellString = "MICellRecords = @miCellRecords, MICellDials = @miCellDials, MICellSaturation = @miCellSaturation," +
                " MICellPercentVolume = @miCellPercentVolume, MICellPassPenetration = @miCellPassPenetration, MICellTotalPassPenFactor =  @miCellTotalPassPenFactor";
            string allString = "AllRecords = @allRecords, AllDials = @allDials, AllSaturation = @allSaturation," +
                " AllPercentVolume = @allPercentVolume, AllPassPenetration = @allPassPenetrationOne, AllTotalPassPenFactor =  @allTotalPassPenFactorOne," +
                " AllPassPenetrationTwo = @allPassPenetrationTwo, AllTotalPassPenFactorTwo =  @allTotalPassPenFactorTwo," +
                " AllPassPenetrationThree = @allPassPenetrationThree, AllTotalPassPenFactorThree =  @allTotalPassPenFactorThree";
            string massString = "MASSRecords = @massRecords, MASSDials = @massDials, MASSSaturation = @massSaturation," +
                " MASSPercentVolume = @massPercentVolume, MASSPassPenetration = @massPassPenetration, MASSTotalPassPenFactor =  @massTotalPassPenFactor";
            string nhString = "NHRecords = @nhRecords, NHDials = @nhDials, NHSaturation = @nhSaturation," +
                " NHPercentVolume = @nhPercentVolume, NHPassPenetration = @nhPassPenetration, NHTotalPassPenFactor =  @nhTotalPassPenFactor";
            string nonContString = "NonContRecords = @nonContRecords, NonContDials = @nonContDials, NonContSaturation = @nonContSaturation," +
                " NonContPercentVolume = @nonContPercentVolume, NonContPassPenetration = @nonContPassPenetration, NonContTotalPassPenFactor =  @nonContTotalPassPenFactor";
            string orString = "ORRecords = @orRecords, ORDials = @orDials, ORSaturation = @orSaturation," +
                " ORPercentVolume = @orPercentVolume, ORPassPenetration = @orPassPenetration, ORTotalPassPenFactor =  @orTotalPassPenFactor";
            string combinedString = "CombinedRecords = @combinedRecords, CombinedDials = @combinedDials, CombinedSaturation = @combinedSaturation," +
                " CombinedPassPenetration = @combinedPercentWorkedOne," +
                " CombinedPassPenetrationTwo = @combinedPercentWorkedTwo," +
                " CombinedPassPenetrationThree =  @combinedPercentWorkedThree";

            query = "UPDATE ESDialsPerList SET " + massCellString + ", " + miCellString + ", " + allString + ", " + massString + ", " +
                nhString + ", " + nonContString + ", " + orString + ", " + combinedString +
                " WHERE CallDate = #" + targetDate.ToString() + "#";

            WriteEarlyStageData(filePath, query);
        }
        else if (departmentSelector.SelectedIndex == 3)
        {

        }
        else if (departmentSelector.SelectedIndex == 4)
        {

        }
    }

    public void WriteEarlyStageData(string filePath, string query)
    {
        string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=" + filePath + ";" +
            @"User Id=;Password=;";

        using (OleDbConnection connection = new OleDbConnection(connectionString))
        using (OleDbCommand command = new OleDbCommand(query, connection))
        {
            try
            {
                connection.Open();
                command.Parameters.AddWithValue("@massCellRecords", Int32.Parse(massCellRecords.Text));
                command.Parameters.AddWithValue("@massCellDials", Int32.Parse(massCellDials.Text));
                command.Parameters.AddWithValue("@massCellSaturation", Double.Parse(massCellSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@massCellPercentVolume", Double.Parse(massCellPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@massCellPassPenetration", Double.Parse(massCellPercentWorked.Text));
                command.Parameters.AddWithValue("@massCellTotalPassPenFactor", Double.Parse(massCellPassPercent.Text));

                command.Parameters.AddWithValue("@miCellRecords", Int32.Parse(miCellRecords.Text));
                command.Parameters.AddWithValue("@miCellDials", Int32.Parse(miCellDials.Text));
                command.Parameters.AddWithValue("@miCellSaturation", Double.Parse(miCellSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@miCellPercentVolume", Double.Parse(miCellPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@miCellPassPenetration", Double.Parse(miCellPercentWorked.Text));
                command.Parameters.AddWithValue("@miCellTotalPassPenFactor", Double.Parse(miCellPassPercent.Text));

                command.Parameters.AddWithValue("@allRecords", Int32.Parse(allRecords.Text));
                command.Parameters.AddWithValue("@allDials", Int32.Parse(allDials.Text));
                command.Parameters.AddWithValue("@allSaturation", Double.Parse(allSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@allPercentVolume", Double.Parse(allPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@allPassPenetrationOne", Double.Parse(allPercentWorkedOne.Text));
                command.Parameters.AddWithValue("@allTotalPassPenFactorOne", Double.Parse(allPassPercentOne.Text));
                command.Parameters.AddWithValue("@allPassPenetrationTwo", Double.Parse(allPercentWorkedTwo.Text));
                command.Parameters.AddWithValue("@allTotalPassPenFactorTwo", Double.Parse(allPassPercentTwo.Text));
                command.Parameters.AddWithValue("@allPassPenetrationThree", Double.Parse(allPercentWorkedThree.Text));
                command.Parameters.AddWithValue("@allTotalPassPenFactorThree", Double.Parse(allPassPercentThree.Text));

                command.Parameters.AddWithValue("@massRecords", Int32.Parse(massRecords.Text));
                command.Parameters.AddWithValue("@massDials", Int32.Parse(massDials.Text));
                command.Parameters.AddWithValue("@massSaturation", Double.Parse(massSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@massPercentVolume", Double.Parse(massPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@massPassPenetration", Double.Parse(massPercentWorked.Text));
                command.Parameters.AddWithValue("@massTotalPassPenFactor", Double.Parse(massPassPercent.Text));

                command.Parameters.AddWithValue("@nhRecords", Int32.Parse(nhRecords.Text));
                command.Parameters.AddWithValue("@nhDials", Int32.Parse(nhDials.Text));
                command.Parameters.AddWithValue("@nhSaturation", Double.Parse(nhSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@nhPercentVolume", Double.Parse(nhPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@nhPassPenetration", Double.Parse(nhPercentWorked.Text));
                command.Parameters.AddWithValue("@nhTotalPassPenFactor", Double.Parse(nhPassPercent.Text));

                command.Parameters.AddWithValue("@nonContRecords", Int32.Parse(nonContRecords.Text));
                command.Parameters.AddWithValue("@nonContDials", Int32.Parse(nonContDials.Text));
                command.Parameters.AddWithValue("@nonContSaturation", Double.Parse(nonContSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@nonContPercentVolume", Double.Parse(nonContPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@nonContPassPenetration", Double.Parse(nonContPercentWorked.Text));
                command.Parameters.AddWithValue("@nonContTotalPassPenFactor", Double.Parse(nonContPassPercent.Text));

                command.Parameters.AddWithValue("@orRecords", Int32.Parse(orRecords.Text));
                command.Parameters.AddWithValue("@orDials", Int32.Parse(orDials.Text));
                command.Parameters.AddWithValue("@orSaturation", Double.Parse(orSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@orPercentVolume", Double.Parse(orPercentTotal.Text.Replace("%","")));
                command.Parameters.AddWithValue("@orPassPenetration", Double.Parse(orPercentWorked.Text));
                command.Parameters.AddWithValue("@orTotalPassPenFactor", Double.Parse(orPassPercent.Text));

                command.Parameters.AddWithValue("@combinedRecords", Int32.Parse(combinedRecords.Text));
                command.Parameters.AddWithValue("@combinedDials", Int32.Parse(combinedDials.Text));
                command.Parameters.AddWithValue("@combinedSaturation", Double.Parse(combinedSaturation.Text.Replace("%","")));
                command.Parameters.AddWithValue("@combinedPercentWorkedOne", Double.Parse(combinedPercentWorkedOne.Text));
                command.Parameters.AddWithValue("@combinedPercentWorkedTwo", Double.Parse(combinedPercentWorkedTwo.Text));
                command.Parameters.AddWithValue("@combinedPercentWorkedThree", Double.Parse(combinedPercentWorkedThree.Text));

                command.ExecuteNonQuery();                    

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

为什么不参数化查询?

string queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = @callDate";
OleDbCommand oleCmd = new OleDbCommand(queryString);
oleCmd.Parameters.Add("@callDate", OleDbType.Date).Value = targetDate;

方法签名的一个小变化也接受OleDbCommand而不是字符串

public void UpdateEarlyStageData(string filePath, OleDbCommand queryCommand)
{
    //Connection string initializer
    using (OleDbConnection connection = new OleDbConnection("connectionString"))
    {
        queryCommand.Connection = connection;
        using (OleDbDataAdapter adapter = new OleDbDataAdapter(queryCommand))
        {
            System.Data.DataTable table = new System.Data.DataTable();
            adapter.Fill(table);
            // assignment operations
        }
    }
}

答案 1 :(得分:0)

将日期值转换为字符串表达式时,您只需要强制使用非本地化格式:

string queryString = "SELECT * FROM ESDialsPerList WHERE CallDate = #" + DateTime.Today.ToString("yyyy'/'MM'/'dd") + "#";
    string 

结果字符串将是#2016/05/02# Access SQL接受的。