Проблема с выполнением хранимой процедуры с рефрактором OUT при использовании ODP.Net, управляемого с помощью библиотеки Enterprise - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь выполнить несколько (3) хранимых процедур одну за другой, используя управляемую ODP.Net с Enterprise Library .Каждая хранимая процедура возвращает OUT курсор , каждый из которых был назван " cur_out ".Что странно, так это то, что первая хранимая процедура всегда возвращает записи, однако последующие вызовы к ExecuteDataSet () для оставшихся двух SP никогда не возвращают никаких записей.Это прекрасно работает с System.Data.OracleClient, поэтому я знаю, что нет никаких проблем с хранимыми процедурами как таковыми.Я не могу понять, почему эти SP ничего не возвращают.Ниже приведен мой пример кода:

DbCommand cmd = DB.GetStoredProcCommand("EBS_EOM_PKG.SP1");
                DB.AddInParameter(cmd, "PI_PARAM1", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM1", param1);
                DB.AddInParameter(cmd, "PI_PARAM2", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM2", param2);
                if (cmd is Oracle.ManagedDataAccess.Client.OracleCommand)
                {
                    OracleParameter cur = new OracleParameter("cur_out", 
                                          OracleDbType.RefCursor, 0, 
                                          ParameterDirection.Output, true, 
                                          0, 0, String.Empty, 
                                          DataRowVersion.Current, 
                                          Convert.DBNull);
                    cmd.Parameters.Add(cur);
                }
                DataSet dsSub = DB.ExecuteDataSet(cmd); <--WORKS i.e. returns records

         cmd = DB.GetStoredProcCommand("EBS_EOM_PKG.SP2");
                DB.AddInParameter(cmd, "PI_PARAM1", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM1", param1);
                DB.AddInParameter(cmd, "PI_PARAM2", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM2", param2);
                if (cmd is Oracle.ManagedDataAccess.Client.OracleCommand)
                {
                    OracleParameter cur = new OracleParameter("cur_out", 
                                          OracleDbType.RefCursor, 0, 
                                          ParameterDirection.Output, true, 
                                          0, 0, String.Empty, 
                                          DataRowVersion.Current, 
                                          Convert.DBNull);
                    cmd.Parameters.Add(cur);
                }
                DataSet dsSub1 = DB.ExecuteDataSet(cmd); <--FAILS i.e. no records returned
               DataTable dt1 = dsSub1.Tables[0];
               dsSub1.Tables.Remove(dt1);
               dt1.TableName = "Ported DataTable 1";//Provide name 
               explicitly to prevent name conflicts with existing datatable
               dsSub.Tables.Add(dt1);

       cmd = DB.GetStoredProcCommand("EBS_EOM_PKG.SP3");
                DB.AddInParameter(cmd, "PI_PARAM1", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM1", param1);
                DB.AddInParameter(cmd, "PI_PARAM2", DbType.AnsiString);
                DB.SetParameterValue(cmd, "PI_PARAM2", param2);
                if (cmd is Oracle.ManagedDataAccess.Client.OracleCommand)
                {
                    OracleParameter cur = new OracleParameter("cur_out", 
                                          OracleDbType.RefCursor, 0, 
                                          ParameterDirection.Output, true, 
                                          0, 0, String.Empty, 
                                          DataRowVersion.Current, 
                                          Convert.DBNull);
                    cmd.Parameters.Add(cur);
                }
                DataSet dsSub2 = DB.ExecuteDataSet(cmd); <--FAILS i.e. no records returned

                DataTable dt2 = dsSub2.Tables[0];

                dsSub2.Tables.Remove(dt2);
                dt2.TableName = "Ported DataTable 2";//Provide name 
                explicitly to prevent name conflicts with existing datatable
                dsSub.Tables.Add(dt2);

Может кто-нибудь указать, что я здесь упускаю?Есть ли что-то, что я могу сделать по-другому?Обратите внимание, что я использую БД Oracle 12c, в которой возникла проблема с возвратом нескольких курсоров ref в одной хранимой процедуре, поэтому необходимо выполнить их отдельно, а затем объединить результат в одном наборе данных.

1 Ответ

0 голосов
/ 19 сентября 2018

Я рекомендую объявлять новые DbCommand cmd2 и DbCommand cmd3 вместо того, чтобы пытаться повторно использовать начальные DbCommand cmd.В прошлом у меня было много проблем с повторным использованием переменных, связанных с параметрами и соединениями Oracle, и многие проблемы, как правило, уходят, если вы просто используете новые переменные для каждого аспекта соединения с базой данных.

В частности, для вашего кода создается впечатление, что вы постоянно добавляете в свой * 1006 одни и те же два параметра * Но я не думаю, что это переустанавливает значение в существующем параметре на новое значение, яЯ думаю, что это добавляет другой, дубликат, параметр в коллекцию параметров, и это вызывает проблемы.

...