Oracle查询在SQL +中工作,但在VB.NET中不返回任何行

时间:2011-10-24 14:12:49

标签: vb.net oracle datetime

帮助,任何想法??

我在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

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' )