Проблема запроса-строки возвращаются при выполнении запроса в SQL navigator, но не в моей программе на C#
обновление:
- Это запрос от отладчика, который был извлечен из строкового разработчика:
{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);