首先,我想指出,我知道要避免在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());
}
}
}
答案 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接受的。