帮助,任何想法??
我在OLED 10.2.0.3.0中使用OLEDB适配器(Oracle OLEDB)。我的代码为查询生成SQL,然后当我将其执行到OLEDBDataReader时,HasRows为False。但是,如果我输出查询字符串的内容,复制并粘贴到SQL +(从同一客户端计算机以相同用户身份登录),则返回993行。是什么给了??
以下是我的代码的一部分:
Dim DB As New OleDb.OleDbConnection(String.Format("{0};Password={1}", ConnectionString, DBPassword))
Dim flowQuerySQL As String
'... code to generate query
Debug.Print(flowQuerySQL)
Dim flowQueryCMD As New OleDb.OleDbCommand(flowQuerySQL, DB)
Dim flowQuery As OleDb.OleDbDataReader = flowQueryCMD.ExecuteReader()
While flowQuery.HasRows
'...handle rows
End While
debug.print语句显示:
SELECT CLASS_ID, OBJECT_ID FROM TDM_SF_PROCESS WHERE CLASS_ID=853 AND TDM_END_TIME >= '01-Jan-2009' AND TDM_END_TIME < '31-May-2009' AND TDM_STATUS <> 1 AND TDM_STATUS <> 2
答案 0 :(得分:2)
我最近刚开始使用VB.NET来对抗Oracle,并且日期是温和的。
到目前为止,这种方法对我有用:
SELECT CLASS_ID, OBJECT_ID
FROM TDM_SF_PROCESS
WHERE CLASS_ID=853
AND TDM_END_TIME >= TO_DATE('01-Jan-2009', 'DD-Mon-YYYY')
AND TDM_END_TIME < TO_DATE('31-May-2009', 'DD-Mon-YYYY')
AND TDM_STATUS <> 1
AND TDM_STATUS <> 2
在我使用“TO_DATE”功能之前它不起作用。希望这也适合你。
我是MS-SQL的人,所以我还没有能够研究其原因的“原因”。启蒙运动,任何人?
答案 1 :(得分:1)
1)您是否正在构建不使用绑定变量的查询?或者您是否为我们手动填写调试输出中的绑定变量?如果您没有使用绑定变量,那么您实际上会在数据库中创建一个巨大的性能问题,因为您将破坏Oracle的共享池。您将创建易受SQL注入攻击攻击的不安全代码。而且你最终会花费大量时间来处理与数据类型,转义字符串等相关的陷阱。
如果您使用绑定变量,您只需在VB.Net应用程序中创建本地日期变量,将它们绑定到您的查询,一切都可以正常工作。这样会更有效率,因为Oracle只需要对语句执行一次硬解析,并且当您使用不同的日期一次又一次地运行查询时,不会使用类似的语句泛洪共享池。
我不是VB开发人员。但是,如果您使用绑定变量,则应使用占位符替换SQL语句中的文字,即
AND TDM_END_TIME >= :early_time
AND TDM_END_TIME < :late_time
AND TDM_STATUS <> :status_1
AND TDM_STATUS <> :status_2
然后,您将在运行时为这些绑定变量提供值,即
flowQueryCMD.Parameters.Add( ":early_time", <<your VB date object>> )
flowQueryCMD.Parameters.Add( ":late_time", <<your VB date object>> )
最后,执行查询
2)如果您没有使用绑定变量,那么您必须确保您的数据类型匹配。 '01 -Jan-2009'是一个字符串,而不是日期,因此Oracle必须隐式地将字符串转换为日期。它通过使用会话的NLS_DATE_FORMAT
来实现。如果您的NLS_DATE_FORMAT
碰巧不是'DD-MON-YYYY',转换将失败(或默默地做一些意外的事情),您将无法获得预期的结果。由于NLS_DATE_FORMAT
对于每个会话都可能不同,因此您绝不想依赖于在任何特定会话中设置的任何特定NLS_DATE_FORMAT
,否则您的代码可能适合您,而您的同事恰好喜欢欧洲日期格式。您的代码可以在一个会话中正常工作(例如,SQL * Plus,即从一个地方获取NLS_DATE_FORMAT
)而不是在另一个会话中(例如,获得它的语言,字符集和日期的.Net应用程序)来自.Net堆栈的格式设置)
有几种方法可以在Oracle中指定日期文字。第一种是使用ANSI日期文字(或时间戳文字)语法(注意ANSI日期文字总是指定为YYYY-MM-DD)
AND tdm_end_time >= date '2009-01-01'
AND tdm_end_time < date '2009-05-31'
第二个选项是使用TO_DATE
功能
AND tdm_end_time >= to_date( '01-Jan-2009', 'DD-MON-YYYY' )
AND tdm_end_time < to_date( '31-May-2009', 'DD-MON-YYYY' )