Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: SQL Server VC++6 BLOB помогите  (Прочитано 15834 раз)
0 Пользователей и 1 Гость смотрят эту тему.
SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« : 05-04-2010 17:27 » 

Доброе время суток,
давно работаю с SQL Server из VC++6 небыло проблем, теперь необходимо сохранить приличный объем данных (32кБ) бинарных данных, и тут косяк, с тем что предлагает студия при создании проекта (там указатель создается), не подключается к базе, как строкой читать из базы получается, а писать в базу никак. Пожалуйста помогите кто знает.
Записан
SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 06-04-2010 09:41 » 

И че никто не знает, ну спасибо за интерес, нарыл ссылку с примером, разберусь сам.
http://support.microsoft.com/kb/190958
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 06-04-2010 09:43 » 

SAndrus, а код покажи, как тебе подсказывать будут то ?
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 06-04-2010 15:37 » 

когда в базе создавал данные varchar[8000],
класс интерфейса создавался типа

char mDann[8001]

а интерфейс колонки:

COLUMN_ENTRY_TYPE(1, DBTYPE_STR, m_mDann)

но как понял если бинарный нуль в начале строки то вся строка теряется

пробовал в базе создать varbinary[8000]
класс создавался с переменной

ISequentialStream* m_mDann;

интерфейс типа:

BLOB_ENTRY(1, IID_ISequentialStream, STGM_READ, m_mDann)

программа выпадала на инструкции MoveNext при откритии RowSet
Записан
SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 08-04-2010 07:37 » 

подскажите, почему функция: m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength );
выдает ошибку при попытке выделения 11288 байтов, а при выделении 4096, на первом цикле и 4096*2 на втором цикле считывания все нормально
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 08-04-2010 07:42 » 

может быть, нужно освобождать в промежутках - CoTaskMemFree
(но не знаю, не пользовался этими функциями)
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 08-04-2010 07:49 » new

там, во втором топике ссылка, программа использует этот механизм, заливает до 15 мегов, а я чет неправильно делаю
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 08-04-2010 07:59 » 

SAndrus, код показывай, что тут ещё можно сказать ? Улыбаюсь
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 08-04-2010 08:12 » 

по ссылке это код примера, ISSHelper там функция сохранения :

HRESULT CISSHelper::Write( const void *pv, ULONG cb, ULONG* pcbWritten )
{
   // Check parameters.
   if ( !pv ) return STG_E_INVALIDPOINTER;
   if ( pcbWritten ) *pcbWritten = 0;
   if ( 0 == cb ) return S_OK;

   // Enlarge the current buffer.
   m_ulLength += cb;

   // Grow internal buffer to new size.
   m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength );
   

   // Check for out of memory situation.
   if ( NULL == m_pBuffer )
   {
      Clear();
      return E_OUTOFMEMORY;
   }

   memset((void*)((BYTE*)m_pBuffer + m_iWritePos),0,m_ulLength);

   // Copy callers memory to internal bufffer and update write position.
   memcpy( (void*)((BYTE*)m_pBuffer + m_iWritePos), pv, cb );
   m_iWritePos += cb;

   // Return bytes written to caller.
   if ( pcbWritten ) *pcbWritten = cb;

   return S_OK;
}

а это функция считывания из базы тоже практически не изменял:

void LoadLongData()
{
      BYTE rgBuffer[4096];
      ULONG ulBytesRead;

      HRESULT hr;
      hr = session.Open( *db );
      if ( FAILED(hr) )
      {
            return;
      }

      // Open rowset.  This will fail if BLOB1234 table does not exist.
      hr = OpenRowset();
      if ( FAILED(hr) )
      {
            return;
      }

      // Position rowset to first (one and only) record.
      hr = MoveFirst();
      if ( FAILED(hr) )
      {
            return;
      }

      if ( DBSTATUS_S_OK != m_mDann_STATUS )
      {
            return;
      }

      // Read data from blob field.
      do
      {
         // Call ISequentialStream::Read using provider's pointer.
         hr = m_mDann->Read( rgBuffer, sizeof(rgBuffer), &ulBytesRead );
         if ( FAILED(hr) )
         {
            return;
         }

         // Stuff data into helper class which is used as a dynamic buffer here.
         hr = ISSHelper.Write( rgBuffer, sizeof(rgBuffer), NULL );
         if ( FAILED(hr) )
         {   
            return;
         };
      }
      while ( sizeof(rgBuffer) == ulBytesRead );
      FreeRecordMemory();
      Close();
}

вызываю вот так:

void CLongDannDlg::OnButton1()
{
   UpdateData();
   CHndlMagnLDann bas;
   UINT vNom=m_IDC_EDIT2;HRESULT hr;
   UINT nom=m_IDC_EDIT1;
   bas.db=&basa;
   bas.sSQLgl.Format("select * from mDann where vnom=%d",vNom);
   bas.LoadLongData();
   if(hr!=S_OK)return;
   BYTE *dn=(BYTE*)bas.ISSHelper.m_pBuffer;
   if(dn!=0)m_IDC_EDIT3.Format("%d %d %d %d %d",dn[nom],dn[nom+1],dn[nom+2],dn[nom+3],dn[nom+4]);
   UpdateData(FALSE);
   
}

basa; - открываю при инициализации диалога
правда создаю это все на базе диалога, хотя там тоже на диалоге сделано, может настроики какие
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 08-04-2010 08:20 » 

поставь остановку сразу после строки
m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength );
и глянь, что вернёт GetLastError()  после возникновения ошибки
(или просто идентификатор "err" в просмотре переменных впиши)
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 08-04-2010 08:24 » 

и err и GetLastError возвращают 0, при выполнении этой функции в третий раз программа останавливается на ассемблерском коде на пользовательском прерываниии
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 08-04-2010 08:30 » 

int 3 ?

когда у менятакое выскакивало - обычно обнаруживалась порча памяти неким способом )))

Рыться в коде некогда сейчас, может вечером
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 08-04-2010 08:34 » 

спасибо, поищу
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 08-04-2010 08:36 » 

обрати внимание, какой адрес памяти показывается при глюке - вроде пишется, какой участок памяти портится - по адресу можно вычислить переменную , которая портится или её память

ещё можно скопировать проект и понемногу отключать всё подряд, пока не станет глюка, и там искать.
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 08-04-2010 09:15 » 

надо же оказалось что функция:

memset((void*)((BYTE*)m_pBuffer + m_iWritePos),0,m_ulLength);

это безобразие и творит, отключил и ее нормально все выделяет
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 08-04-2010 09:28 » 

можно было так записать, но что то у тебя неверно с одной из этих трёх переменных - гляди под отладчиком значения. Может, не инициализарованы


memset(((BYTE*)m_pBuffer)[m_iWritePos],0,m_ulLength);

если всё
Записан

SAndrus
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 08-04-2010 10:05 » 

ага, разобрался m_ulLength это общая длина пакета, а надо часть которую пишем, исправил спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines