Squeak.ru - шаблоны программирования

Вызов параметризованной хранимой процедуры в C#, которая возвращает значения через курсор и сохраняет их в DataTable

У меня есть хранимая процедура, которая запускает запрос выбора через курсор и возвращает курсор (исходный запрос выбора более сложный, я его сократил).

CREATE OR REPLACE PROCEDURE GETASSIGNEDROLES(IN V_USER_ID INTEGER) SPECIFIC GETASSIGNEDROLES DYNAMIC RESULT SETS 1 LANGUAGE SQL NOT DETERMINISTIC EXTERNAL ACTION READS SQL DATA CALLED ON NULL INPUT INHERIT SPECIAL REGISTERS 
BEGIN 
    DECLARE TEMP_CURSOR CURSOR WITH HOLD WITH RETURN TO CLIENT FOR 
        SELECT DISTINCT ROLE_ID, ROLE_NAME FROM ROLE ORDER BY ROLE_NAME FOR READ ONLY WITH UR; 
    IF V_USER_ID IS NOT NULL AND V_USER_ID > 0 THEN 
        OPEN TEMP_CURSOR; 
    END IF; 
END;

Теперь я не смог найти ни одного примера, показывающего, как получить значения из хранимой процедуры, возвращающей курсор. Я полагаю, что это то же самое, что и для любой другой хранимой процедуры, содержащей только оператор выбора?

Кроме того, моя база данных — DB2, поэтому синтаксис немного отличается. Пока у меня есть следующий код после просмотра нескольких вопросов о SO. Но я не нашел ни одного вопроса, используя Datatable и параметры передачи в CMD, это правильно?

DataTable DT = new DataTable();
using (var connection = new DB2Connection(ConnectionString))
{
  //connection.Open(); //open/close connection will be done implicitely by the DataAdapter.
  using (DB2Command cmd = connection.CreateCommand())
  {
      cmd.CommandText = "GETASSIGNEDROLES";
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVUserID, DB2Type.Integer)).Value = userDo.User_ID;
      //cmd.CommandTimeout = CommandTimeout; //wait time before terminating the attempt to execute a command and generating an error in secs

      using (var da = new DB2DataAdapter(cmd))
      {
          da.Fill(DT);
      }
      DT.TableName = TableName;
      return DT;
  }
}

  • P.S. Это первый раз, когда я задаю вопрос, пожалуйста, полегче со мной. Я новичок в этом. Кроме того, почему в Интернете так мало информации о DB2. Все для SQLServer, очень мало статей, связанных с DB2. В документации нет примеров на них. 03.05.2018

Ответы:


1

Необходимо изучить все связанные/связанные страницы Центра знаний Db2 для вашей версии Db2, которые описывают общеязыковые процедуры выполнения C# .net.

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

Если ваш сервер Db2 работает в Microsoft-Windows или если вы установили примеры Db2 для Windows с полным клиентом сервера данных (расположение по умолчанию:

\program files\ibm\sqllib\samples\dotnet\cs

), то вы можете посмотреть примеры DataTable для C# там, а также онлайн в Центре Знаний - "DbDatMap.cs" и связанные с ним файлы и "SpClient.cs" и его зависимости

Пожалуйста, проверьте, почему вы заполняете DataTable DT, но return DTT.

Если вы отлаживаете свой код, вы должны иметь возможность перебирать строки в DT после da.Fill(DT); завершается успешно.

Консольное приложение, использующее большую часть вашего синтаксиса, отлично работает для меня, единственное изменение заключается в том, что я использовал уже существующее соединение и предоставил параметр varchar для моей хранимой процедуры вместо целого числа (но это не может иметь значения).

03.05.2018
  • Хранимая процедура завершена и уже работает со многими ранее существовавшими программами/утилитами. Кроме того, я хочу использовать DB2DataAdapter, а не DB2DataReader, поскольку не хочу, чтобы результат возвращался построчно. Я хочу это в datatable. У меня уже есть подобный рабочий код, который просто выполняет запрос и сохраняет результат в таблице данных, но я делаю это впервые с параметрами и возвращаю значение. 03.05.2018
  • › Кажется, вам не хватает da.SelectCommand перед вызовом Fill. Я думал, что это подразумевается, когда я использую следующий код: using (var da = new DB2DataAdapter(cmd)) вместо этого: DB2DataAdapter da = new DB2DataAdapter(); da.SelectCommand = cmd; 03.05.2018

  • 2

    Итак, я, наконец, заставил это работать. Насчет открытых курсоров, видимо так и делается в DB2. Курсор остается открытым для чтения клиентским приложением. Помогла эта ссылка: https://bytes.com/topic/db2/answers/465403-how-do-well-anything-db2-sql

    Использованная хранимая процедура (изменено из вопроса):

    CREATE OR REPLACE PROCEDURE GETASSIGNEDROLES(IN V_USER_ID INTEGER, IN V_BUSINESS_ENTITY_ID INTEGER) SPECIFIC GETASSIGNEDROLES DYNAMIC RESULT SETS 1 LANGUAGE SQL NOT DETERMINISTIC EXTERNAL ACTION READS SQL DATA CALLED ON NULL INPUT INHERIT SPECIAL REGISTERS 
    BEGIN 
        DECLARE TEMP_CURSOR CURSOR WITH HOLD WITH RETURN TO CLIENT FOR 
            SELECT DISTINCT ROLE_ID, ROLE_NAME FROM ROLE ORDER BY ROLE_NAME FOR READ ONLY WITH UR; 
        IF V_USER_ID IS NOT NULL AND V_USER_ID > 0 THEN 
            OPEN TEMP_CURSOR; 
        END IF; 
    END;
    

    Функция в C# для вызова хранимой процедуры и сохранения полученных данных в таблице данных:

    public DataTable GetAssignedRolesForUser(string ConnectionString, string TableName, User userDo)
            {
                //LogManager.EventLog("Inside GetAssignedRolesForUser");
                try
                {
                    DataTable DTT = new DataTable();
                    //See if UserID exists check is required here
                    using (var connection = new DB2Connection(ConnectionString))
                    {
                        //connection.Open(); //open/close connection will be done implicitely by the DataAdapter.
                        using (DB2Command cmd = connection.CreateCommand())
                        {
                            cmd.CommandText = DataBaseObjects.spGetAssignedRoles;
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVUserID, DB2Type.Integer)).Value = userDo.User_ID;
                            cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVBusinessEntityID, DB2Type.Integer)).Value = ConfigurationManager.AppSettings["BusinessEntity"];
                            //cmd.CommandTimeout = CommandTimeout; //wait time before terminating the attempt to execute a command and generating an error in secs
    
                            using (var da = new DB2DataAdapter(cmd))
                            {
                                da.Fill(DTT);
                            }
                            DTT.TableName = TableName;
                            return DTT;
                        }
                    }
                }
                catch (Exception)
                {
                    //LogManager.EventLog("[Error] Inside GetAssignedRolesForUser: " + ex.Message);
                    throw;
                }
            }
    

    Код для вызова функции C#:

    DataTable DtRoles = <Call function here>
                    foreach (DataRow row in DtRoles.Rows)
                    {
                        list.Add(Convert.ToInt32(row["ROLE_ID"].ToString()));
                    }
    
    22.05.2018
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...