我们目前在几个内部产品中使用ADO.Net,其中一个产品必须使用OleDB查询Microsoft Access数据库。我们现在遇到的问题是,当OleDbDataAdapter.Fill
执行并且直接在Microsoft Access的SQL视图中执行时,其中一个查询不会产生相同的结果。
查询如下所示:
SELECT DISTINCT t1.*
FROM tableOne AS t1
INNER JOIN tableTwo AS t2 ON t2.tableOne_no = t1.tableOne_no
WHERE t1.status = 'A'
AND t2.tableThree_no = @p_tableThree_no
AND t2.status = 1
AND (t2.startDate IS NULL OR (YEAR(t2.startDate) <= @p_year AND MONTH(t2.startDate) <= @p_month))
AND (t2.endDate IS NULL OR (YEAR(t2.endDate) >= @p_year AND MONTH(t2.endDate) >= @p_month))
我们使用Microsoft ACE OLEDB 12和ADO.Net:
使用以下代码查询数据库Dim oDataSet As New DataSet()
Using oSqlConnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\NetworkDrive\database.mdb;User Id=admin;Password=password;")
Using oSqlCommand As New OleDbCommand(p_sQuery, oSqlConnection)
oSqlCommand.Parameters.AddWithValue("@p_tableThree_no", 1111)
oSqlCommand.Parameters.AddWithValue("@p_year", 2013)
oSqlCommand.Parameters.AddWithValue("@p_month", 7)
oSqlCommand.CommandType = CommandType.Text
Using oDataAdapter As New OleDbDataAdapter()
oDataAdapter.SelectCommand = oSqlCommand
oSqlConnection.Open()
oDataAdapter.Fill(oDataSet)
End Using
End Using
End Using
不知何故,从OleDB执行查询所提供的结果数量与在Microsoft Access中执行相同查询(Access具有正确数量的结果)相同。当执行具有不同@p_tableThree_no
值的相同查询时,一切似乎都没问题。某些Text字段中的特定值是否可能导致OleDB忽略该特定情况下的行?没有错误消息,代码运行成功,只有错误的结果。
在Google和StackOverflow上搜索此问题几乎没有提供帮助,因为我找到的唯一解决方案是LIKE
语句的问题(使用%而不是*)和参数名称冲突,这些都不相关我的情况。
我错过了什么吗?对于OleDB,查询是否过于复杂?我应该用括号括起来吗?我不知道我做错了什么。
原来这个查询错误,没人(包括我自己)乍一看就确定了它。当我注意到MONTH(t2.startDate) <= @p_month
没有任何意义,如果日期是2012-11与2013-07相比时,我正在从stratch重写查询。我仍然不知道为什么查询结果在Access中直接执行并在弹出窗口中提供参数时“错误地纠正”,但这是我不愿意解决的另一个谜。我接受了@HansUp的答案,因为他确实向我提供了双方都相同的查询,而且他让我怀疑SQL本身。
答案 0 :(得分:0)
ACE.OLEDB忽略参数名称,因此OleDb查询可能会变得混乱,因为@p_year
和@p_month
参数在SQL命令中重复,但它们只在{{1}中指定一次收集。我倾向于尝试使用OleDbCommand.Parameters
作为参数占位符并重复最后两个参数(即使用五个?
语句而不是三个)。
答案 1 :(得分:0)
在SQL语句中定义参数,然后像以前一样提供代码中的值。
不要担心Parameters.AddWithValue
中的参数名称。 OleDb忽略参数名称......你可以做.AddWithValue("Hello World!", 1111)
并且它不会改变任何东西。但是,您必须按照Access期望的顺序提供参数,并且我希望添加PARAMETERS
子句可以避免混淆。
PARAMETERS
p_tableThree_no Long,
p_year Long,
p_month Long;
SELECT DISTINCT t1.*
FROM
tableOne AS t1
INNER JOIN
tableTwo AS t2
ON t2.tableOne_no = t1.tableOne_no
WHERE
t1.status = 'A'
AND t2.tableThree_no = p_tableThree_no
AND t2.status = 1
AND (t2.startDate IS NULL
OR (YEAR(t2.startDate) <= p_year AND MONTH(t2.startDate) <= p_month))
AND (t2.endDate IS NULL
OR (YEAR(t2.endDate) >= p_year AND MONTH(t2.endDate) >= p_month))