На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS

Дорогие друзья! Поздравляем вас с Новым 2025 годом!

Всем удачи, успеха и благополучия!

msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Вызов хранимой процедуры и хождение по выборке вперед и назад
    Есть код который прекрасно работает в Visual Studio 2010, но который не работает с набором инструментов платформы выше чем Visual Studio 2010.
    ExpandedWrap disabled
      #include "afxdb.h"
       
      class CTestRecordset : public CRecordset
      {
      public:
          CTestRecordset(CDatabase* pDatabase = NULL) :
              CRecordset(pDatabase)
          {
              m_nFields = 1;
          };
       
          int m_rc;
       
          virtual void DoFieldExchange(CFieldExchange* pFX);
      };
       
      void CTestRecordset::DoFieldExchange(CFieldExchange* pFX)
      {
          pFX->SetFieldType(CFieldExchange::outputColumn);
          RFX_Int(pFX, (LPCTSTR)"rc", m_rc);
      }
       
      void CTestDlg::OnBnClickedButton1()
      {
          CString t;
       
          CDatabase db;
          db.OpenEx((LPCTSTR)"DSN=[I]ODBCName[/I];UID=[I]LoginName[/I];PWD=[I]Password[/I]", CDatabase::useCursorLib | CDatabase::noOdbcDialog);
          CTestRecordset rs(&db);
       
          rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL test2}", CRecordset::readOnly | CRecordset::executeDirect | CRecordset::noDirtyFieldCheck);
       
          t.Format("Open: %d", rs.m_rc);
          ::AfxMessageBox(t);
       
          rs.MoveNext();
          t.Format("MoveNext: %d", rs.m_rc);
          ::AfxMessageBox(t);
       
          rs.MovePrev();
          t.Format("MovePrev: %d", rs.m_rc);
          ::AfxMessageBox(t);
       
          rs.Close();
          db.Close();
      }

    Хранимая процедура:
    ExpandedWrap disabled
      create proc dbo.test2
      as
      begin
          declare @rc1 int = 1
          declare @rc2 int = 2
       
          select @rc1
              union all
          select @rc2
      end
      go

    Например, если в Visual Studio 2022 в настройках проекта указан набор инструментов платформы = "Visual Studio 2022 (v143)",
    то происходит падение на
    Цитата
    rs.MovePrev()

    с ошибкой
    Цитата
    "Fetch type out of range"

    Я запустил профайлер и стал смотреть что в нем происходит проходя по шагам функцию
    Цитата
    CTestDlg::OnBnClickedButton1

    и увидел что после выполнения
    Цитата
    rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL test2}", CRecordset::readOnly | CRecordset::executeDirect | CRecordset::noDirtyFieldCheck);

    в профайлере появляются следующие ошибки
    Цитата
    Неправильный синтаксис около ключевого слова "declare".

    Цитата
    Оператор SQL выполняется напрямую; без курсора.

    после чего идет вызов хранимой процедуры.
    Последняя ошибка объясняет почему происходит падение на rs.MovePrev(), т.к. использование курсора было принудительно отменено.

    Если этот же код проходить по шагам в Visual Stusio 2010, то данных ошибок в профайлере нет и rs.MovePrev() выполняется корректно.

    Подскажите кто знает, что можно сделать что бы данный код работал на более старших версиях чем Visual Stusio 2010?
      В этой теме я в районе нуля, но у меня есть друг ChatGPT ;) Он посоветовал слегка изменить код хранимой процедуры:

      ExpandedWrap disabled
        CREATE PROCEDURE dbo.test2
        AS
        BEGIN
            SELECT 1 AS Value
            UNION ALL
            SELECT 2 AS Value
        END
        GO

      Но это, сам понимаешь, метод научного тыка. На авось.
        Цитата Majestio @
        В этой теме я в районе нуля, но у меня есть друг ChatGPT ;) Он посоветовал слегка изменить код хранимой процедуры:

        ExpandedWrap disabled
          CREATE PROCEDURE dbo.test2
          AS
          BEGIN
              SELECT 1 AS Value
              UNION ALL
              SELECT 2 AS Value
          END
          GO

        Но это, сам понимаешь, метод научного тыка. На авось.

        В том то и дело что обычно в хранимке перед финальным select'ом почти всегда есть сложные расчеты с объявлением переменных и т.д.
        Поэтому я намеренно для примера сделал такую хранимку.
          Тогда, я думаю, имеет смысл - сперва не кодить, а погонять сперва в каком-нибудь SQL-клиенте (рекомендую этот). Записать там хранимые процедуры, выполнить там ручные SQL-запросы, с задействованием написанной хранимой процедуры. И убедиться, что этот "первый шаг" отрабатывает нормально.
            Цитата Majestio @
            Тогда, я думаю, имеет смысл - сперва не кодить, а погонять сперва в каком-нибудь SQL-клиенте (рекомендую этот). Записать там хранимые процедуры, выполнить там ручные SQL-запросы, с задействованием написанной хранимой процедуры. И убедиться, что этот "первый шаг" отрабатывает нормально.

            Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций.
            Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте.
            Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам.
            Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы.
              Цитата Evgi1980 @
              Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций.
              Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте.
              Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам.
              Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы.

              Я соболезную :whistle: Но разве тебе не интересно самому - почему у тебя в новой студии "Неправильный синтаксис около ключевого слова "declare""?
                Цитата Majestio @
                Цитата Evgi1980 @
                Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций.
                Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте.
                Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам.
                Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы.

                Я соболезную :whistle: Но разве тебе не интересно самому - почему у тебя в новой студии "Неправильный синтаксис около ключевого слова "declare""?

                С хранимой процедурой все в порядке.
                Библиотеки из последней версии platform toolset перестали нормально работать с sql.
                  Цитата Evgi1980 @
                  С хранимой процедурой все в порядке.

                  Мне просто интересно - это ты проверил, или это ты уверен?
                    Цитата Majestio @
                    Цитата Evgi1980 @
                    С хранимой процедурой все в порядке.

                    Мне просто интересно - это ты проверил, или это ты уверен?

                    Я ее лично запускал в SQL Managment Studio.
                    Да и по телу хранимки видно что все там нормально.
                    Сообщение отредактировано: Evgi1980 -
                      Скину тебе ответ ChatGPT, может быть поможет. Дальше, увы, не знаю.

                      Цитата
                      Проблема с кодом

                      Судя по вашему описанию, ошибка синтаксиса в хранимой процедуре может быть связана с изменениями в версии SQL Server или в настройках подключения, используемых в Visual Studio 2022. Давайте рассмотрим несколько возможных причин и решений.

                      Возможные причины ошибки

                      1. Изменения в SQL Server: Если вы используете более новую версию SQL Server, возможно, некоторые синтаксические правила изменились. Убедитесь, что ваша хранимая процедура соответствует стандартам SQL для вашей версии сервера.
                      2. Проблемы с подключением: Проверьте, правильно ли настроено подключение к базе данных в Visual Studio 2022. Возможно, параметры подключения отличаются от тех, что использовались в VS 2010.
                      3. Использование executeDirect: Попробуйте убрать флаг CRecordset::executeDirect. Этот флаг может вызывать проблемы с выполнением хранимых процедур в некоторых версиях Visual Studio. Попробуйте использовать просто CRecordset::snapshot и CRecordset::readOnly.

                      Рекомендации по исправлению

                      Попробуйте изменить ваш код следующим образом:

                      ExpandedWrap disabled
                        rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL dbo.test2}", CRecordset::readOnly | CRecordset::noDirtyFieldCheck);

                      Обратите внимание на добавление dbo. перед именем процедуры. Это может помочь, если у вас есть несколько схем в базе данных.

                      Проверка хранимой процедуры

                      Также убедитесь, что ваша хранимая процедура действительно создана и доступна в базе данных. Вы можете выполнить следующий запрос в SQL Server Management Studio, чтобы проверить:

                      ExpandedWrap disabled
                        EXEC dbo.test2;

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

                      Если после всех этих изменений проблема не решится, попробуйте посмотреть на сообщения об ошибках, которые предоставляет Visual Studio, чтобы получить больше информации о том, что именно не так.
                        Цитата Majestio @
                        Скину тебе ответ ChatGPT, может быть поможет. Дальше, увы, не знаю.

                        Цитата
                        Проблема с кодом

                        Судя по вашему описанию, ошибка синтаксиса в хранимой процедуре может быть связана с изменениями в версии SQL Server или в настройках подключения, используемых в Visual Studio 2022. Давайте рассмотрим несколько возможных причин и решений.

                        Возможные причины ошибки

                        1. Изменения в SQL Server: Если вы используете более новую версию SQL Server, возможно, некоторые синтаксические правила изменились. Убедитесь, что ваша хранимая процедура соответствует стандартам SQL для вашей версии сервера.
                        2. Проблемы с подключением: Проверьте, правильно ли настроено подключение к базе данных в Visual Studio 2022. Возможно, параметры подключения отличаются от тех, что использовались в VS 2010.
                        3. Использование executeDirect: Попробуйте убрать флаг CRecordset::executeDirect. Этот флаг может вызывать проблемы с выполнением хранимых процедур в некоторых версиях Visual Studio. Попробуйте использовать просто CRecordset::snapshot и CRecordset::readOnly.

                        Рекомендации по исправлению

                        Попробуйте изменить ваш код следующим образом:

                        ExpandedWrap disabled
                          rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL dbo.test2}", CRecordset::readOnly | CRecordset::noDirtyFieldCheck);

                        Обратите внимание на добавление dbo. перед именем процедуры. Это может помочь, если у вас есть несколько схем в базе данных.

                        Проверка хранимой процедуры

                        Также убедитесь, что ваша хранимая процедура действительно создана и доступна в базе данных. Вы можете выполнить следующий запрос в SQL Server Management Studio, чтобы проверить:

                        ExpandedWrap disabled
                          EXEC dbo.test2;

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

                        Если после всех этих изменений проблема не решится, попробуйте посмотреть на сообщения об ошибках, которые предоставляет Visual Studio, чтобы получить больше информации о том, что именно не так.

                        Пробовал ставить разные вариации флагов при открытии рекордсета, эффекта не дает.
                        Хранимку, как я уже писал, запускал в SQL Managment Studio через exec dbo.test2, все прекрасно работает.
                        Сообщение отредактировано: Evgi1980 -
                          Evgi1980, жаль что не смог помочь, сорян! :(

                          Просто я никогда не работал ни с компиляторами M$, ни с его SQL-сервером, ни разу. Думал прокатит "на обще-стандартных подходах". Не прокатило :(

                          Вопрос, так, для уточнения ... в коде:

                          ExpandedWrap disabled
                            rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL dbo.test2}", CRecordset::readOnly | CRecordset::noDirtyFieldCheck);

                          Ты пробовал действительно CALL dbo.test2, а не твой старый CALL test2?

                          Но всеже, и если нет и не прокатило ... ты разбирался, почему твой код в новой системе выдаёт "Оператор SQL выполняется напрямую, без курсора"? Мне почему-то чуйка подсказывает, что последующие операторы rs.MoveNext(); и rs.MovePrev(); не могут работать без "курсора".

                          Чисто совет от балды:

                          1) Прочитай, действительно ли операторы rs.MoveNext(); и rs.MovePrev(); могут/не могут работать без курсора?
                          2) Выясняй причину "Оператор SQL выполняется напрямую, без курсора". Если эта причина - ищи как сделать "с курсором". Но есть ещё момент ... этот подход вполне может зафиксится как "устаревший", времени то прошло много! И если "да" смотри "современный" варик!
                            Цитата Majestio @
                            ты разбирался, почему твой код в новой системе выдаёт "Оператор SQL выполняется напрямую, без курсора"

                            В этом сообщении и есть вся проблема.
                            Это сообщение не появляется с использованием библиотек mfc100, но появляется с использованием mfc140.
                            Причину определить не удалось.
                              Еще один вопросик-уточнение: та программа, которая норм работает, и та, которая глючит - они подключаются к одному и тому же серверу БД?
                                MovePrev команда выбрасывает ошибку на forward-only рекордсетах. Возможно, что одна среда создает static а другая forward-only курсор.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0468 ]   [ 16 queries used ]   [ Generated: 20.01.25, 05:44 GMT ]