 Вызов хранимой процедуры и хождение по выборке вперед и назад
    Вызов хранимой процедуры и хождение по выборке вперед и назад
    
  |  | Наши проекты: Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту | |
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.107] | 
|   | 
 | 
 Правила раздела Visual C++ / MFC / WTL (далее Раздела)
    Правила раздела Visual C++ / MFC / WTL (далее Раздела)
   FAQ Раздела
 FAQ Раздела   Обновления для FAQ Раздела
 Обновления для FAQ Раздела    Поиск по Разделу
 Поиск по Разделу   MSDN Library Online
 MSDN Library Online| Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) | 
 Вызов хранимой процедуры и хождение по выборке вперед и назад
    Вызов хранимой процедуры и хождение по выборке вперед и назад
    
  | 
         
         
          
           Сообщ.
           #1
          
          , 
          
         
         | |
|  |  Есть код который прекрасно работает в Visual Studio 2010, но который не работает с набором инструментов платформы выше чем Visual Studio 2010.   #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(); } Хранимая процедура:   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? | 
| 
         
         
          
           Сообщ.
           #2
          
          , 
          
         
         | |
|  |  В этой теме я в районе нуля, но у меня есть друг ChatGPT   Он посоветовал слегка изменить код хранимой процедуры:   CREATE PROCEDURE dbo.test2 AS BEGIN     SELECT 1 AS Value     UNION ALL     SELECT 2 AS Value END GO Но это, сам понимаешь, метод научного тыка. На авось. | 
| 
         
         
          
           Сообщ.
           #3
          
          , 
          
         
         | |
|  | Цитата Majestio @  В этой теме я в районе нуля, но у меня есть друг ChatGPT   Он посоветовал слегка изменить код хранимой процедуры:   CREATE PROCEDURE dbo.test2 AS BEGIN     SELECT 1 AS Value     UNION ALL     SELECT 2 AS Value END GO Но это, сам понимаешь, метод научного тыка. На авось. В том то и дело что обычно в хранимке перед финальным select'ом почти всегда есть сложные расчеты с объявлением переменных и т.д. Поэтому я намеренно для примера сделал такую хранимку. | 
| 
         
         
          
           Сообщ.
           #4
          
          , 
          
         
         | |
|  |  Тогда, я думаю, имеет смысл - сперва не кодить, а погонять сперва в каком-нибудь SQL-клиенте (рекомендую этот). Записать там хранимые процедуры, выполнить там ручные SQL-запросы, с задействованием написанной хранимой процедуры. И убедиться, что этот "первый шаг" отрабатывает нормально.   | 
| 
         
         
          
           Сообщ.
           #5
          
          , 
          
         
         | |
|  | Цитата Majestio @  Тогда, я думаю, имеет смысл - сперва не кодить, а погонять сперва в каком-нибудь SQL-клиенте (рекомендую этот). Записать там хранимые процедуры, выполнить там ручные SQL-запросы, с задействованием написанной хранимой процедуры. И убедиться, что этот "первый шаг" отрабатывает нормально. Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций. Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте. Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам. Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы. | 
| 
         
         
          
           Сообщ.
           #6
          
          , 
          
         
         | |
|  | Цитата Evgi1980 @  Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций. Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте. Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам. Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы. Я соболезную  Но разве тебе не интересно самому - почему у тебя в новой студии "Неправильный синтаксис около ключевого слова "declare""? | 
| 
         
         
          
           Сообщ.
           #7
          
          , 
          
         
         | |
|  | Цитата Majestio @  Цитата Evgi1980 @  Дело в том что это огромный проект написанный с использованием Visual Studio 2010, который внедрен во множество организаций. Огромное количество хранимых процедур так же давно уже написаны и работают в данном проекте. Была попытка перевести проект на Visual Studio 2022 с использованием последнего набора инструментов платформы, которая привела к данным проблемам. Все примеры которые были приведены в данной теме сильно упрощены для демонстрации проблемы. Я соболезную  Но разве тебе не интересно самому - почему у тебя в новой студии "Неправильный синтаксис около ключевого слова "declare""? С хранимой процедурой все в порядке. Библиотеки из последней версии platform toolset перестали нормально работать с sql. | 
| 
         
         
          
           Сообщ.
           #8
          
          , 
          
         
         | |
|  | Цитата Evgi1980 @  С хранимой процедурой все в порядке. Мне просто интересно - это ты проверил, или это ты уверен? | 
| 
         
         
          
           Сообщ.
           #9
          
          , 
          
         
         | |
|  | Цитата Majestio @  Цитата Evgi1980 @  С хранимой процедурой все в порядке. Мне просто интересно - это ты проверил, или это ты уверен? Я ее лично запускал в SQL Managment Studio. Да и по телу хранимки видно что все там нормально. | 
| 
         
         
          
           Сообщ.
           #10
          
          , 
          
         
         | |
|  |  Скину тебе ответ ChatGPT, может быть поможет. Дальше, увы, не знаю. Цитата  Проблема с кодом Судя по вашему описанию, ошибка синтаксиса в хранимой процедуре может быть связана с изменениями в версии SQL Server или в настройках подключения, используемых в Visual Studio 2022. Давайте рассмотрим несколько возможных причин и решений. Возможные причины ошибки Рекомендации по исправлению Попробуйте изменить ваш код следующим образом:   rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL dbo.test2}", CRecordset::readOnly | CRecordset::noDirtyFieldCheck); Обратите внимание на добавление dbo. перед именем процедуры. Это может помочь, если у вас есть несколько схем в базе данных. Проверка хранимой процедуры Также убедитесь, что ваша хранимая процедура действительно создана и доступна в базе данных. Вы можете выполнить следующий запрос в SQL Server Management Studio, чтобы проверить:   EXEC dbo.test2; Если процедура выполняется без ошибок, значит, проблема скорее всего в коде C++ или в настройках подключения. Если после всех этих изменений проблема не решится, попробуйте посмотреть на сообщения об ошибках, которые предоставляет Visual Studio, чтобы получить больше информации о том, что именно не так. | 
| 
         
         
          
           Сообщ.
           #11
          
          , 
          
         
         | |
|  | Цитата Majestio @  Скину тебе ответ ChatGPT, может быть поможет. Дальше, увы, не знаю. Цитата  Проблема с кодом Судя по вашему описанию, ошибка синтаксиса в хранимой процедуре может быть связана с изменениями в версии SQL Server или в настройках подключения, используемых в Visual Studio 2022. Давайте рассмотрим несколько возможных причин и решений. Возможные причины ошибки Рекомендации по исправлению Попробуйте изменить ваш код следующим образом:   rs.Open(CRecordset::snapshot, (LPCTSTR)"{CALL dbo.test2}", CRecordset::readOnly | CRecordset::noDirtyFieldCheck); Обратите внимание на добавление dbo. перед именем процедуры. Это может помочь, если у вас есть несколько схем в базе данных. Проверка хранимой процедуры Также убедитесь, что ваша хранимая процедура действительно создана и доступна в базе данных. Вы можете выполнить следующий запрос в SQL Server Management Studio, чтобы проверить:   EXEC dbo.test2; Если процедура выполняется без ошибок, значит, проблема скорее всего в коде C++ или в настройках подключения. Если после всех этих изменений проблема не решится, попробуйте посмотреть на сообщения об ошибках, которые предоставляет Visual Studio, чтобы получить больше информации о том, что именно не так. Пробовал ставить разные вариации флагов при открытии рекордсета, эффекта не дает. Хранимку, как я уже писал, запускал в SQL Managment Studio через exec dbo.test2, все прекрасно работает. | 
| 
         
         
          
           Сообщ.
           #12
          
          , 
          
         
         | |
|  |  Evgi1980, жаль что не смог помочь, сорян!    Просто я никогда не работал ни с компиляторами M$, ни с его SQL-сервером, ни разу. Думал прокатит "на обще-стандартных подходах". Не прокатило  Вопрос, так, для уточнения ... в коде:   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 выполняется напрямую, без курсора". Если эта причина - ищи как сделать "с курсором". Но есть ещё момент ... этот подход вполне может зафиксится как "устаревший", времени то прошло много! И если "да" смотри "современный" варик! | 
| 
         
         
          
           Сообщ.
           #13
          
          , 
          
         
         | |
|  | Цитата Majestio @  ты разбирался, почему твой код в новой системе выдаёт "Оператор SQL выполняется напрямую, без курсора" В этом сообщении и есть вся проблема. Это сообщение не появляется с использованием библиотек mfc100, но появляется с использованием mfc140. Причину определить не удалось. | 
| 
         
         
          
           Сообщ.
           #14
          
          , 
          
         
         | |
|  |  Еще один вопросик-уточнение: та программа, которая норм работает, и та, которая глючит - они подключаются к одному и тому же серверу БД?   | 
|   | 
         
         
          
           Сообщ.
           #15
          
          , 
          
         
         | 
|  |  MovePrev команда выбрасывает ошибку на forward-only рекордсетах. Возможно, что одна среда создает static а другая forward-only курсор.   |