Oracle Managed Data Reader возвращает DBNull для одной таблицы базы данных

#c# #.net #oracle #oracle-manageddataaccess

#c# #.net #Oracle #oracle-manageddataaccess

Вопрос:

Проблема:

Я использую клиент Oracle managed data access для подключения к базе данных Oracle eBS. При выборе значения из одной таблицы я получаю результат; при изменении таблицы я получаю нулевое значение.

Справочная информация:

В моем клиенте SQLDeveloper я могу подключиться к базе данных и выполнить следующие запросы:

 SELECT MSIB.SEGMENT1 
FROM APPS.MTL_SYSTEM_ITEMS_B MSIB 
WHERE MSIB.ORGANIZATION_ID = 255 AND MSIB.SEGMENT1 = '03F.211';
-- 1 ROW RETURNED - VALUE OF 03F.211

SELECT MC.SEGMENT1 
FROM APPS.MTL_CATEGORIES_VL MC 
WHERE MC.SEGMENT1 = 'A0042I';
-- 1 ROW RETURNED - VALUE OF A0042I
  

Затем в C # я подключаюсь к базе данных с точно такими же учетными данными (так что это не должно быть проблемой с разрешениями базы данных).

Запуская этот код, я получаю окно сообщения, возвращающее то, что я ожидал: 03F.211

  OracleConnection oradbcon = new OracleConnection(strOracleConString);
 oradbcon.Open();
 strQuery = "SELECT MSIB.SEGMENT1 FROM APPS.MTL_SYSTEM_ITEMS_B MSIB WHERE MSIB.ORGANIZATION_ID = 255 AND MSIB.SEGMENT1 = "   ":ITEM_CODE";
 // strQuery = "SELECT MC.SEGMENT1 FROM APPS.MTL_CATEGORIES_VL MC WHERE MC.SEGMENT1 = "   ":ITEM_CODE";
 OracleCommand oradbcmd = new OracleCommand(strQuery, oradbcon);
 oradbcmd.CommandType = CommandType.Text;
 OracleParameter p_item_code = new OracleParameter();
 p_item_code.OracleDbType = OracleDbType.Varchar2;
 p_item_code.Value = "03F.211";
 // p_item_code.Value = "A0042I";
 oradbcmd.Parameters.Add(p_item_code);
 OracleDataReader oradbdr = oradbcmd.ExecuteReader();
 oradbdr.Read();
 strProductMinor = oradbdr.GetString(0).ToString();
 MessageBox.Show(strProductMinor);
  

Но при запуске кода с переключением этих строк комментариев я получаю ошибку, указывающую на значение database null:

 OracleConnection oradbcon = new OracleConnection(strOracleConString);
oradbcon.Open();
// strQuery = "SELECT MSIB.SEGMENT1 FROM APPS.MTL_SYSTEM_ITEMS_B MSIB WHERE MSIB.ORGANIZATION_ID = 255 AND MSIB.SEGMENT1 = "   ":ITEM_CODE";
strQuery = "SELECT MC.SEGMENT1 FROM APPS.MTL_CATEGORIES_VL MC WHERE MC.SEGMENT1 = "   ":ITEM_CODE";
OracleCommand oradbcmd = new OracleCommand(strQuery, oradbcon);
oradbcmd.CommandType = CommandType.Text;
OracleParameter p_item_code = new OracleParameter();
p_item_code.OracleDbType = OracleDbType.Varchar2;
// p_item_code.Value = "03F.211";
p_item_code.Value = "A0042I";
oradbcmd.Parameters.Add(p_item_code);
OracleDataReader oradbdr = oradbcmd.ExecuteReader();
oradbdr.Read();
strProductMinor = oradbdr.GetString(0).ToString();
MessageBox.Show(strProductMinor);
  

Ошибка DBNull

Что может привести к тому, что один запрос вернет результаты, а другой — нет?

(Наконец — простите мое незнание C #, если что-то из вышеперечисленного выглядит некрасиво. Годы опыта Oracle — первая программа на C # в истории … :))

Комментарии:

1. Вы пытались запустить запрос с жестко заданными значениями вместо параметров? Это вернуло правильные значения? Я никогда не подключался к Oracle с помощью c #, поэтому я не уверен в синтаксисе параметризованного запроса. Может возникнуть проблема с привязкой значения. Но я полагаю, вам следует каким-то образом сообщить вашему параметру Oracle его имя.

2. Спасибо @derpirscher — я действительно это сделал. Полезно, но я разобрался…

3. Я выяснил, в чем заключается моя собственная проблема. APPS.MTL_CATEGORIES_VL — это представление в Oracle. В этом представлении он просматривает другое представление: MTL_CATEGORIES_TL MTL_CATEGORIES_TL — это представление «переведенный язык», что означает, что оно вернет результаты для языка, к которому подключен ваш сеанс Oracle. Разработчик SQL объявляет этот контекст. Соединитель .NET этого не делает. Я должен выяснить, как это сделать, или вернуться к базовым таблицам…

4. Попробуйте следующее: 1- Просто установите для вашего thread.CurrentCulture язык, соответствующий вашей базе данных перед вызовом; 2 — поиграйте с этим OracleGlobalization info = conn.GetSessionInfo();...conn.SetSessionInfo(info)

Ответ №1:

Проблема в языке.

APPS.MTL_CATEGORIES_VL — это представление, которое имеет другое представление в своем определении: MTL_CATEGORIES_TL

Представления, заканчивающиеся на TL, являются «переведенным языком», что означает, что они возвращают результаты только для языка вашего сеанса базы данных.

Разработчик SQL объявляет язык по умолчанию при подключении. Клиент .NET не является.

Мне либо нужно выяснить, как объявить язык, либо переписать мои запросы, чтобы использовать базовые таблицы, у которых нет языка.

Редактировать: Была жалоба на то, что это был не фактический ответ, а объяснение.

Вот фактический код, который является ответом:

     try // Open Connection
    {
        oradbcon = new OracleConnection(yourConnectionStringHere);
        oradbcon.Open();
        OracleGlobalization orainfo = oradbcon.GetSessionInfo();
        orainfo.Language = "AMERICAN"; // Explicitly Set Language
        oradbcon.SetSessionInfo(orainfo);
    }
  

Комментарии:

1. Это не ответ, как это исправить, а скорее объяснение того, что не так. Вы должны публиковать ответы только после устранения проблемы. И это объяснение вы можете добавить к своему первоначальному вопросу.