Переключение на Главную Страницу Страницы: 1 ... 4 5 [6] 7 8 ... 16 ОтправитьПечать
Очень популярная тема (более 25 ответов) Провайдер OLE DB для ТП (число прочтений - 69092 )
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #75 - 05. Октября 2007 :: 07:32
Печать  
а ты пробовал параметризированным запросом укладывать данные в курсор?
  
Наверх
ICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Провайдер OLE DB для ТП
Ответ #76 - 05. Октября 2007 :: 07:53
Печать  
spock писал(а) 05. Октября 2007 :: 07:32:
а ты пробовал параметризированным запросом укладывать данные в курсор?


Чтобы не мешать обсуждению провайдера создал отдельную тему
http://www.1cpp.ru/forum/YaBB.pl?num=1191570663
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #77 - 10. Октября 2007 :: 02:43
Печать  
Случилось страшное!!! Провайдер для ТП и параметризованные запросы оказались несовместимыми! При умолчальном значении OLEDB_SERVICES для ключа HKEY_CLASSES_ROOT\CLSID\{50BAEED9-ED25-11D2-B97B-000000000000} параметризованные запросы не работают. При нулевом значении такие запросы работают, но подыхает провайдер  Плачущий Похоже, при этом отваливается возможность получения IRowsetLocate. Ладно, переделал под использование IRowset и оно заработало. (Но, блин, YAHOOею от этих приколов Улыбка)

Итак:
- параметризованные запросы в 1С++ восстановлены.
- в OLEDBCommand вставлено свойство "РазмерПорцииСтрок": по сколько строк за раз забирать из выборки данных OLE DB. Насколько оно влияет на скорость не проверял.

Описание изменений в 1С++.
Основные изменения внесены в класс COLEDBCommand. Суть изменений: метод funcExecuteStatement вынесен в отдельный класс - OleDb::CResult, обрабатывающий результат запроса (в виде IRowset) и предоставляющий методы для получения информации о колонках и методы для получения значений строк в объекты CValue. В результате заполнение ТЗ в funcExecuteStatement свелось к этому простому коду:

Код
Выбрать все
	CValue Value;
	ULONG nRow = 0;
	while (Result.GetNextRow ()) {
		pVT->NewRow(nRow);
		for (ULONG nCol = 0; nCol < cCols; ++nCol) {
			Result.GetFieldValue(nCol, Value);
			pVT->SetValue(Value, nCol, nRow);
		}

		++nRow;
	}
 



Краткое описание OleDb::CResult.
Обязанности класса: подготовка к парсингу полученного результата (инициализация служебных данных), пребразование данных результата в объекты CValue, получение информации о составе колонок. Навигацию по результату сам класс не производит - это обязанность производных классов.

Класс является абстрактным базовым классов для классов CResultSequentialAccess и CResultDirectAccess.
Класс принимает в конструкторе интерфейс IRowset.
В класс перенесены из COLEDBCommand методы Binding, CreateAccessor, GetType1C, FindKindCol, AddOffset, GetErrorDescription.

Код преобразования данных OLE DB в CValue вынесен в метод GetFieldValue. Этот код был очень огромным (очень сложно было его понимать), поэтому он разделен на несколько простых функций: ReadLongField, ReadNumericField, ReadBoolField, ReadDateField, ReadTimestampField, ReadWideStringField, Read1SField.

Открытый интерфейс OleDb::CResult:
CResult (IRowset *pRowset) - конструктор
bool IsEmpty () const - проверка на пустой результат
ULONG GetNumFields () const - получить количество полей
CString const &GetFieldName (ULONG Field) const - получить имя поля
CType const &GetFieldType (ULONG Field) const - получить тип значения поля
bool GetFieldValue (ULONG Field, CValue &Value) - получить значение поля текущей строки

Класс OleDb::CResultSequentialAccess - производный от OleDb::CResult. Работает с результатом при помощи последовательного доступа. Открытый интерфейс:
CResultSequentialAccess (IRowset *pRowset, UINT RowsChunk = DEFAULT_ROWS_CHUNK) - конструктор, принимает результат запроса и размер порции строк.
bool GetNextRow () - получение следующей строки.

Класс OleDb::CResultDirectAccess - производный от OleDb::CResult. Позволяет работать с результатом запроса при помощи произвольного доступа - т.е. позволяет получить строку по индексу. Открытый интерфейс:
CResultDirectAccess (IRowset *pRowset) - конструктор
bool GetRow (ULONG Row) - получить строку по индексу.

Изменения, обеспечивающие взаимодействие с другими ВК
COLEDBCommand::CreateCommand объявлена как DLLEXPORT. Это позволяет сторонней ВК создать команду, имея контекст "OLEDBData".

Добавлен класс OleDb::CCommandProxy. Объявление этого класса должно быть одинаково как для 1С++, так и для другой ВК. CCommandProxy по сути является простой оберткой над смартпойнтером для COLEDBCommand (он реализует так называемую идиому pimpl). Класс содержит ряд методов идентичным методам COLEDBCommand. Эти методы просто переадресуют вызов в COLEDBCommand. CCommandProxy объявлен как DLLEXPORT. Класс позволяет вызывать методы COLEDBCommand, не зная структуры COLEDBCommand. Поэтому допустима модификация этого класса без необходимости перекомпиляции сторонних ВК.

Добавлены классы OleDb::CResultProxy, OleDb::CResultSequentialAccessProxy и OleDb::CResultDirectAccessProxy. Это DLLEXPORT-обертки, реализующие идиому pimpl для классов OleDb::CResult, OleDb::CResultSequentialAccess и OleDb::CResultDirectAccess.

В COLEDBCommand добавлены методы ExecuteStatementExternalSequential и ExecuteStatementExternalDirect. Методы выполняют запрос и возвращают объект класса OleDb::CResultSequentialAccessProxy или OleDb::CResultDirectAccessProxy - в зависимости от того типа доступа, который требуется.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #78 - 10. Октября 2007 :: 02:54
Печать  
Еще некоторые изменения:

Про переход на std::vector я уже писал. Вообще, тот класс, который использовался раньше, хоть и простой, но очень опасный. У него не закрыты конструктор копирования и оператор присваивания. Также у него есть неявное приведение к T *. Это приводит к следующим потенциальным проблемам:
- скомпилируется код delete Object (из-за неявного приведения)
- возможно незаметное копирование объектов класса. Т.к. конструктор копирования и оператор присваивания не определены, то компилятор создает стандартные - они работают как простое почленное копирование объектов. Соответственно, если где-то скрыто произойдет копирование, то это приведет к многократному освобождению одной и той же памяти. Что произойдет в результате - не известно. Может вообще ничего не случится, может быть освобожден чужой блок или может быть просто тихо испорчена память. Последний случай самый неприятный. В OLE DB все может работать прекрасно, все тесты будут проходиться, но чей-то чужой код будет падать.

Нашел лик:
Код
Выбрать все
bool COLEDBCommand::Binding(IRowset_& pIRowset, ULONG* pnCols, DBBINDING_& pDBBindings, COLEDBFldsInf_& pColInfo1C, ULONG* pcMaxRowSize, bool& HasKindField) const

 далее код

	     if(pColumnsInfo[nCol].dwFlags & DBCOLUMNFLAGS_ISLONG)
	     {
		    pColInfo1C[nCol].m_bIsLong	= true;

		    pDBBindings[nCol].pObject	= new DBOBJECT;
 


В коде OleDb::CResult добавил в класс vector<DBOBJECT>, в Binding вместо new записал взятие адреса элемента вектора.

Еще нашел возможность для лика в procSetParam. Изменил определение m_ParamList с CList на std::vector. Плюс заменил хранение указателей на хранение самих объектов. Упростилась работа со списком параметров. Также vector здесь точно подходит гораздо лучше CList, т.к. в COLEDBCommand постоянно происходит доступ к параметрам по индексу. Для CList такой доступ имеет линейную сложность. Для вектора - константную.

Да. fatal.ru сейчас не работает - выложил компоненты и исходники на http://uzhast.fromru.su/vfp.oledb.provider/
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Провайдер OLE DB для ТП
Ответ #79 - 10. Октября 2007 :: 08:08
Печать  
Uzhast писал(а) 30. Сентября 2007 :: 17:51:
1) Интерфейс CDataProvider - скрещение ужа с ежом. Присутствует методы, которые позволяют ТП управлять провайдером, вместе с методами, которыми провайдер может управлять ТП. ИМХО, нужно в этом интерфейсе сделать метод, которым ТП передаст интерфейс для взаимодействия с ним. К тому же в невиртуальных методах торчат детали реализации: HWND и пересылка сообщений. Это не хорошо. Представим ситуацию: ТП на клиентской машине, а провайдер может лежать либо на той же машине, либо на сервере. Если бы вместо невиртуальных функций был полноценный интерфейс, то реализовать такую систему можно было бы проще и красивее. А так еще и фиктивный HWND делать...

+1
Причем даже в этом виде интерфейс них#ра нерасширяем
А когда мне понадобилось передавать из провайдера в ТП дополнительные данные, было неудобно. Улыбка

Цитата:
2) Не понравилась реализация перетаскивания ползунка прокрутки. Похоже, при этом фетчатся строки, пока не дофетчим до нужной.

На SQL нет перетаскивиния ползунка, поэтому проблема в широких кругах малоизвестна. Улыбка
Плюс на каждый фетч - заполнение CGridRow, отработка ПриВыводеСтроки и т.д.

Цитата:
Однако ест много памяти.

А почему, интересно?
Вроде строки освобождаться должны?

Цитата:
ИМХО, для ТП нужен еще один метод в CDataProvider: аналогичный QueryRows, но с дополнительным параметром: смещение от переданной строки. Такая штука вроде неплохо ложится как на XBase методы доступа, так на SQL.

На SQL ложится в общем случае плохо. Печаль
Но там оно к счастью и не нужно.
Закон фостерс Улыбка

Цитата:
3) Лик строк в быстром поиске? В методе QuickSearch провайдер должен сделать поиск и, если нашел, вызывать SetCurrentRow. В SetCurrentRow передается указатель на строку, которую надо сделать текущей. Эта строка в ТП не освобождается. Тут что, подразумевается, что освобождать должен провайдер? ИМХО, нелогично. Во-первых, это не указано в документации. Во-вторых, при обычной выборке данных строки удаляет всегда ТП. В-третьих, реализация ТП может смениться и оно может захотеть временно хранить эту строку для своих целей.

Да мне кажется - простой лик, забыли просто про строчку и все.

Мне вообще не нравится текущее управление временем жизни CDataRow.
Это было первое, что пришлось переделать на подсчет ссылок.
Иначе ты сохраняешь в неком механизме ссылку на CDataRow, а она выходя из окна ТП, разрушается.
Ну, можно и по-другому решить, но, как водится нахуа.

Я правда, простую пару AddRef() /Release() добавил в CDataRow.
Сейчас, наверное, через смартпойнтеры сделал бы, а то ведь никто уважать не будет Очень довольный
  

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Провайдер OLE DB для ТП
Ответ #80 - 10. Октября 2007 :: 08:19
Печать  
Uzhast писал(а) 10. Октября 2007 :: 02:54:
Вообще, тот класс, который использовался раньше, хоть и простой, но очень опасный. У него не закрыты конструктор копирования и оператор присваивания. Также у него есть неявное приведение к T *. Это приводит к следующим потенциальным проблемам:

Мне тоже кажется, что опасный.
Инварианты класса (p) плохо, что в паблике, да плюс непреодолимое желание использовать Alloc и Release общественно опасным образом.
К примеру, вызывать Release с последующим разрушением класса (и повторным освобождением памяти).
Не для чайников, класс, однозначно.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #81 - 10. Октября 2007 :: 08:28
Печать  
kms писал(а) 10. Октября 2007 :: 08:08:
На SQL нет перетаскивиния ползунка, поэтому проблема в широких кругах малоизвестна. Улыбка
Плюс на каждый фетч - заполнение CGridRow, отработка ПриВыводеСтроки и т.д.

Нет перетаскивания - это в штатных гридах? Или в ТП тоже нет? Но, в любом случае, с перетаскиванием, ИМХО, нужно что-то делать. Оно вроде и на просмотре гигантских ТЗ должно тормозить Улыбка

kms писал(а) 10. Октября 2007 :: 08:08:
Цитата:
Однако ест много памяти.

А почему, интересно?
Вроде строки освобождаться должны?

Да это просто из-за провайдера. Он же "статический" - забирает весь набор данных и держит. Поэтому если мы попросим отобразить в ТП весь журнал документов, то он его целиком и затянет Улыбка Это в "динамике" все должно стать шоколадным (а вот станет или нет - еще вопрос).

kms писал(а) 10. Октября 2007 :: 08:08:
Цитата:
ИМХО, для ТП нужен еще один метод в CDataProvider: аналогичный QueryRows, но с дополнительным параметром: смещение от переданной строки. Такая штука вроде неплохо ложится как на XBase методы доступа, так на SQL.

На SQL ложится в общем случае плохо. Печаль
Но там оно к счастью и не нужно.
Закон фостерс Улыбка

А чего так? Это и про "ложимость" и про "не нужность"? А может вообще SQL-провайдер на вариант курсора перетянуть (по тому же принципу, что я думаю для "динамического" провайдера сделать)? Тогда уж точно все нормально ляжет Улыбка

kms писал(а) 10. Октября 2007 :: 08:08:
Цитата:
3) Лик строк в быстром поиске?

Да мне кажется - простой лик, забыли просто про строчку и все.

При ближайшем рассмотрении оказалось, что это не лик, а недочет в документации. Строка должна освобождаться самим провайдером. Недочет очень неприятный. Ибо догадаться трудно, потому что обычно строки освобождаются в ТП. Последствия неприятны - лики. А чтобы установить истину, надо анализировать исходники ТП.

kms писал(а) 10. Октября 2007 :: 08:08:
Мне вообще не нравится текущее управление временем жизни CDataRow.
Это было первое, что пришлось переделать на подсчет ссылок.
Иначе ты сохраняешь в неком механизме ссылку на CDataRow, а она выходя из окна ТП, разрушается.
Ну, можно и по-другому решить, но, как водится нахуа.

Мне тоже не нравится. Правда, немного по другой причине: мало ли как провайдер захочет память выделять? Может, он свой аллокатор захочет использовать? Для повышения скорости или для "уменьшения фрагментации хипа", например. Ну и вообще, мало ли где провайдер может быть реализован - может он сидит в левой DLL со своей левой CRT со своим левым хипом. Поэтому удалять выделенные там объекты в хипе 1С++ - провальное мероприятие.

А проблему сохраненных ссылок можно еще решить через weak_ptr Улыбка

kms писал(а) 10. Октября 2007 :: 08:08:
Я правда, простую пару AddRef() /Release() добавил в CDataRow.
Сейчас, наверное, через смартпойнтеры сделал бы, а то ведь никто уважать не будет Очень довольный

Будет, будет Улыбка
А поводу "стратегии управления жизнью строк" нужно вообще хорошо подумать. Может и правда лучше будет все сделать на COM, чтобы провайдеры можно было химичить на чем-нибудь типа VB/Delphi, чтобы народ потянулся Улыбка
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #82 - 10. Октября 2007 :: 08:37
Печать  
kms писал(а) 10. Октября 2007 :: 08:19:
Мне тоже кажется, что опасный.
Инварианты класса (p) плохо, что в паблике, да плюс непреодолимое желание использовать Alloc и Release общественно опасным образом.
К примеру, вызывать Release с последующим разрушением класса (и повторным освобождением памяти).
Не для чайников, класс, однозначно.

А про Alloc я, кстати, не подумал Улыбка Вообще да - случайно после рефакторинга появится второй Alloc без Release - и потечем.

Вообще, запугали разработчиков совсем... spock уже опасается использовать vector из стандартной библиотеки и вынужден делать велосипеды. Если бы spock'у на такие вещи время тратить не надо было бы, то, чувствую, у нас уже оледебических провайдеров было столько, что хоть ж...ой жуй Улыбка
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #83 - 10. Октября 2007 :: 09:15
Печать  
Uzhast писал(а) 10. Октября 2007 :: 08:28:
А поводу "стратегии управления жизнью строк" нужно вообще хорошо подумать. Может и правда лучше будет все сделать на COM, чтобы провайдеры можно было химичить на чем-нибудь типа VB/Delphi, чтобы народ потянулся Улыбка

+1
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #84 - 10. Октября 2007 :: 09:31
Печать  
Перезалил архив с бинарниками. В прошлый раз забыл положить тестовую обработку.
  
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #85 - 10. Октября 2007 :: 09:55
Печать  
Uzhast писал(а) 10. Октября 2007 :: 09:31:
Перезалил архив с бинарниками. В прошлый раз забыл положить тестовую обработку.

Мужчина, а как вы смотрите на то, чтобы получить зеленые штаны? Не надо будет выкладывать архивы, а можно будет сразу коммитить в cvs.

Если положительно, то жду вас по адресу fe собака alterplast точка ru или в айсикью 1156 три 5003
  
Наверх
www  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #86 - 10. Октября 2007 :: 10:17
Печать  
fez писал(а) 10. Октября 2007 :: 09:55:
Мужчина, а как вы смотрите на то, чтобы получить зеленые штаны? Не надо будет выкладывать архивы, а можно будет сразу коммитить в cvs.

Наверное, ради единоразовой правки зеленые штаны это перебор Улыбка А насчет коммита... Еще ведь spock ничего не сказал. Вот щас придет, обматерит тут всех, скажет, что ему тут все поломали на хрен, и ага Улыбка
  
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #87 - 10. Октября 2007 :: 10:27
Печать  
Uzhast писал(а) 10. Октября 2007 :: 10:17:
Еще ведь spock ничего не сказал. Вот щас придет, обматерит тут всех

Это да, это он любит Смех
Ну ок, ждем спока.
  
Наверх
www  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Провайдер OLE DB для ТП
Ответ #88 - 10. Октября 2007 :: 12:11
Печать  
Uzhast писал(а) 10. Октября 2007 :: 08:28:
Нет перетаскивания - это в штатных гридах? Или в ТП тоже нет?

Ну на SQL базах и ТП и штатные контролы себя так ведут - там тянуть нельзя, можно только мотать, вверх-вниз, по строчке или по странице.
Это первое, что огорчает пользователей при переходе на SQL Улыбка
И, в принципе, в динамическом провайдере OLEDB скорее всего будет так же.

Цитата:
Но, в любом случае, с перетаскиванием, ИМХО, нужно что-то делать. Оно вроде и на просмотре гигантских ТЗ должно тормозить Улыбка

Это точно, где-то даже болтается мой старый комментарий на эту тему.

Цитата:
А чего так? Это и про "ложимость" и про "не нужность"? А может вообще SQL-провайдер на вариант курсора перетянуть (по тому же принципу, что я думаю для "динамического" провайдера сделать)? Тогда уж точно все нормально ляжет Улыбка

Ну, теоретически, чтобы эффективно сместиться на n строк вниз или вверх, эти строки придется по-любому запростить у SQL сервера от некоторой точки привязки, т.е. random access, как для ТЗ или fixed оледбнутого провайдера, не светит.
Можно, к примеру, внести в интерфейс "QueryRows" вирт. метод "промотать n строк", пустой для SQL провайдеров - а для произвольных будет очень эффективно (fetch цикл будет не нужен).
Я помню, ты что-то такое и предлагал.

Цитата:
При ближайшем рассмотрении оказалось, что это не лик, а недочет в документации.

т.е. Fetch отдает строку на откуп ТП, а SetCurrentRow - нет?..
наверное, неудобно будет (тут помню - тут не помню) Улыбка

Цитата:
Строка должна освобождаться самим провайдером.

kms писал(а) 10. Октября 2007 :: 08:08:
Мне вообще не нравится текущее управление временем жизни CDataRow.
Цитата:
Мне тоже не нравится. Правда, немного по другой причине: мало ли как провайдер захочет память выделять?


Вот это точно.

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

Цитата:
А поводу "стратегии управления жизнью строк" нужно вообще хорошо подумать. Может и правда лучше будет все сделать на COM, чтобы провайдеры можно было химичить на чем-нибудь типа VB/Delphi, чтобы народ потянулся Улыбка

Глобально Улыбка
Может быть сначала для народа сделать прокси-поставщика, с открытыми интерфейсам...
Но тема нужная, лучшие люди уже высказывались за Улыбка
  

De quelle planète es-tu?
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Провайдер OLE DB для ТП
Ответ #89 - 10. Октября 2007 :: 13:00
Печать  
kms писал(а) 10. Октября 2007 :: 12:11:
Ну, теоретически, чтобы эффективно сместиться на n строк вниз или вверх, эти строки придется по-любому запростить у SQL сервера от некоторой точки привязки, т.е. random access, как для ТЗ или fixed оледбнутого провайдера, не светит.

Если говорить конкретно о SQL Server, то API серверных курсоров позволяет и random доступ, и получение нескольких строк одним обращением к API (конечно, не для всех типов курсоров). Не знаю, впрочем, доступен ли этот функционал средствами ODBC-драйвера без прямого обращения к API.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: 1 ... 4 5 [6] 7 8 ... 16
ОтправитьПечать