2011-10-24 26 views
0

ヘルプ、任意のアイデア??OracleクエリはSQL +で動作しますが、VB.NETで行を返しません

Oracle 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

結果は1つだけですか?あなたは現在消費しているHasRowsは間違っていますか? – SQLMason

+0

コマンドを実行した後の次のステートメントはWhileFlowQuery.HasRowsです。しかし、私はクエリから日付を削除しようとしましたが、今は 'HasRows'が' True'です。何故ですか? Oracleが望むものとは異なる形式の日付を必要とするOleDbについて何かありますか?私は日付と時間を試しましたが、それは私にORA-01861を与えました。 –

答えて

2

私は最近、Oracleのに対して、VB.NETの作業を開始している、と日付がtempermentalです。

このアプローチは、これまで私のために働いています

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の男です。なぜ、これがなぜ機能するのか、なぜ「なぜ」を研究することができませんでした。啓蒙、誰ですか?

+0

+1 duh、私の古いコードのいくつかを見直した後、私もTO_DATEを使用しています。何らかの理由で、文字列がOracleシステム形式でない限り、正しく解析されません。 Infact私はこれを使用します:to_date('10/24/2011 '、' mm/dd/yyyy ')、さらにAutoHotKeyとしてそれを持っています。 – SQLMason

+0

ダーン、私はそれが行くと思った! CLASS_ID = 862、TDM_END_TIME> = TO_DATE( '1-Jan-2009'、 'DD-Mon-YYYY')、TDM_END_TIME 1 AND TDM_STATUS <> 2' Still HasRows = False –

+0

これを無視してください!クラスID 862には行がありません。 853、それは働いたように見えます。ありがとう!!!! –

1

1)バインド変数を使用しないクエリを作成していますか?または、デバッグ出力のバインド変数を手動で入力していますか?バインド変数を使用していない場合は、Oracleの共有プールを破棄するため、データベースに大量のパフォーマンス問題が生じることになります。あなたは、SQLインジェクション攻撃に対して脆弱な安全でないコードを作成します。

バインド変数を使用していた場合は、VB.Netアプリケーションでローカルの日付変数を作成するだけで簡単に行えます。それらをクエリにバインドし、すべてが一般的に機能します。これは、Oracleが文を一度ハード解析するだけで済むため、異なる日付で何度も何度もクエリを実行したときに、同じような文で共有プールをあふれさせることはないので、ずっと効率的です。

私はVB開発者ではありません。あなたがバインド変数を使用している場合しかし、あなたはその後、すなわち

最後に
flowQueryCMD.Parameters.Add(":early_time", <<your VB date object>>) 
flowQueryCMD.Parameters.Add(":late_time", <<your VB date object>>) 

、実行時にこれらのバインド変数の値を提供する、すなわち

AND TDM_END_TIME >= :early_time 
AND TDM_END_TIME < :late_time 
AND TDM_STATUS <> :status_1 
AND TDM_STATUS <> :status_2 

、プレースホルダを使用してSQL文でリテラルを置き換えます

2)バインド変数を使用していない場合は、データ型が一致していることを確認する必要があります。 '01-Jan-2009 'は日付ではなく文字列であるため、Oracleは文字列を暗黙的に日付に変換する必要があります。これは、セッションのNLS_DATE_FORMATを使用して行います。 NLS_DATE_FORMATが「DD-MON-YYYY」にならない場合、変換は失敗します(または予期しないことが起こります)。期待した結果が得られません。 NLS_DATE_FORMATはセッションごとに異なる可能性があるため、特定のセッションに特定のNLS_DATE_FORMATが設定されている場合は、決してそのコードを使用することはできません。あなたのコードは、1つのセッション(例えば、SQL * Plus、そのNLS_DATE_FORMATを1つの場所から取得しています)では正常に動作し、別のセッション(例えば、a。.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') 
+0

+1。 Oracleの新機能とその用語:バインド変数付きの例を投稿できますか? –

関連する問題