Запрос Oracle работает в SQL +, но не возвращает строк в VB.NET - PullRequest
0 голосов
/ 24 октября 2011

Помогите, есть идеи ??

Я использую адаптер OLEDB (Oracle OLEDB) с Oracle 10.2.0.3.0. Мой код генерирует 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 ]

2 голосов
/ 24 октября 2011

Я только недавно начал работать с 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 голос
/ 24 октября 2011

1) Вы строите запрос, который не использует переменные связывания?Или вы вручную заполняете переменные связывания в своем отладочном выводе для нас?Если вы не используете переменные связывания, вы реально создадите огромную проблему с производительностью в своей базе данных, потому что собираетесь разрушить общий пул Oracle.Вы собираетесь создать небезопасный код, уязвимый для атак с использованием SQL-инъекций.И в конечном итоге вы потратите много времени на изучение проблем, связанных с типами данных, экранированием строк и т. Д.

Если бы вы использовали переменные связывания, вы просто создали бы локальные переменные даты в своем VB.Чистое приложение, свяжите их с вашим запросом, и все будет в целом работать.Это было бы намного эффективнее, поскольку Oracle нужно было бы только выполнить жесткий анализ оператора один раз и не заполнять общий пул аналогичными операторами, когда вы снова и снова выполняете запрос с разными датами.

IЯ не разработчик 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 всегда указываются как ГГГГ-ММ-ДД)

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' )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...