Проблема запроса-строки возвращаются при выполнении запроса в SQL navigator, но не в моей программе на C#

enter image description here

обновление:

- Это запрос от отладчика, который был извлечен из строкового разработчика:

{SELECT * FROM FCR.V_REPORT WHERE DATE BETWEEN to_date('14/09/2001' , 'dd/mm/yyyy') AND to_date('30/09/2011' , 'dd/mm/yyyy')}

Если вы удалите фигурные скобки и разместите их в навигаторе, это сработает.

Оригинал:

у меня проблема при запуске моей программы. Запрос в SQL navigator возвращает 192 строки, но при запуске запроса на c#(visual studio 2010) запрос возвращает 0 строк. Ниже приведен мой код c# :

public static DataTable GetReport(string date1, string date2)
{
  DatabaseAdapter dba = DatabaseAdapter.GetInstance();
  string SqlQuery =
    string.Format(@"SELECT * 
                  FROM FCR.V_REPORT 
                  WHERE DATE BETWEEN to_date('{0}' , 'dd/mm/yyyy')
                    AND to_date('{1}' , 'dd/mm/yyyy')", date1, date2);
  OracleDataReader reader = dba.QueryDatabase(SqlQuery);
  DataTable dt = new DataTable();
  dt.Load(reader);
  int temp = dt.Rows.Count;
  return dt;
}

это запрос, который я использую в SQL navigator (который возвращает 192 строки):

SELECT * 
FROM FCR.V_REPORT
WHERE DATE BETWEEN to_date('01/01/2001' , 'dd/mm/yyyy')
AND to_date('30/09/2011' , 'dd/mm/yyyy')

6 ответов


попробуйте отбросить представление и создать снова. Убедитесь, что вы получили псевдонимы правильно тоже.


Я держу пари, что даты, переданные из вашей программы c#, отличаются, потому что ваш оператор sql идентичен. Поставьте точку останова и убедитесь, что даты точно такие же. Также убедитесь, что date1 и date2 передаются в соответствующем порядке.


при решении такого рода проблем обычно лучше не делать слишком много предположений относительно того, откуда происходит ошибка. Если у вас есть доступ к коробке, я бы запустил трассировку и убедился, что выполняемые операторы действительно идентичны. Если они идентичны, вы знаете, что у вас есть программная ошибка на стороне приема или обработки вашего приложения.

вы можете изменить свой оператор, чтобы вставить результаты во временную таблицу и проверить, что на 192 строки вы ожидаете там. Если вы выполняете тот же оператор, и временная таблица показывает, что вы получаете результаты, которые ожидаете, вы еще больше сузили проблему и можете начать искать ошибки приложения.


предполагая, что ваш код c# отправляет правильный запрос в базу данных, Oracle может выполнить один и тот же запрос по-разному в зависимости от сеанса. Возможно, вам придется задействовать DBA, чтобы понять это (например, посмотрев на фактический выполненный оператор в V$sql) или, по крайней мере, исключить эти странные случаи.

NLS_DATE_FORMAT

Если столбец даты хранится в виде строки, будет неявное преобразование в дату. Если SQL Navigator использует другой NLS_DATE_FORMAT, чем C# преобразование может создавать разные даты. Хотя, если бы они были разными, есть хороший шанс, что вы получите ошибку, а не только 0 строк.

Виртуальная Частная База Данных

VPD может добавить предикат к каждому запросу, возможно, используя другую информацию о сеансе. Например, если программа, которая создала сеанс, похожа на " % Navigator%", она может добавить "где 1 = 0" к каждому запросу. (Я знаю это звучит безумно, но я видел нечто очень похожее.)

Расширенный Запрос Переписать

это предназначено для материализованных представлений. Но некоторые люди используют его для исправления производительности, вроде сохраненных контуров. И некоторые злые люди используют его, чтобы переписать ваш запрос в совершенно другой запрос. Различные параметры сеанса, такие как QUERY_REWRITE_INTEGRITY и CURSOR_SHARING, могут объяснить, почему запрос работает на одном сеансе, но не на другом. Говоря о CURSOR_SHARING, это может привести к некоторым редким проблемам, если он установлен на аналогичный или FORCE.


Я часто сталкивался с той же ситуацией с другими инструментами разработки и SQL Server. В моем случае я обнаружил, что в инструменте запроса у меня будет два выхода: записи в datagrid и сообщение "затронутые строки" в области результатов. Однако в моей среде разработки я бы не увидел данных (если бы не проверил наличие дополнительных наборов данных). По какой-то причине он вернет строки, затронутые как 1-й результирующий набор. Когда я отключил параметр rowcount в самом запросе, данные показали в обоих местах.

вы также можете использовать анализатор протокола (например, эфирная) и захват трафика TCP/IP, чтобы убедиться, что запросы идентичны по проводу. Это тоже помогло мне в трудную минуту.

удачи.

jl


Мне интересно, это та же проблема, что и ваш вопрос здесь.

строку.Вызов формата не указывает формат значений date1 и date2 в самой строке SQL. Следовательно, он использует DateTime по умолчанию.ToString () date1 и date2, которые могут быть чем-то вроде "16/09/2011 12:23:34" и поэтому не соответствуют формату, указанному в вашем операторе to_date.

попробуйте это:

   string SqlQuery = string.Format(@"SELECT * FROM V_REPORT WHERE DATE BETWEEN 
                                   to_date('{0:dd/MM/yyyy}' , 'dd/mm/yyyy')
                                   AND 
                                   to_date('{1:dd/MM/yyyy}' , 'dd/mm/yyyy')", 
                                   date1, 
                                   date2);