Відключений рекордсет ADO

Наведіть, будь ласка, приклад (бажано на C++), який створює та використовує "відключений" рекордсет за допомогою ADO.

Відповіли: 12

Мда. Не все так просто.

--- // set "cursor location" property spTargetRecordset->PutCursorLocation(ADO: :adUseClient); // open recordset spTargetRecordset->Open(bstrTTableName, _variant_t((IDispatch*)dbconn.m_spConnec tion), ADO::adOpenStatic, ADO::adLockBatchOptimistic, (long)ADO :: adCmdTable); // try to disconnect recordset spTargetRecordset->PutActiveConnection(V T_EMPTY); ---

Незважаючи на те, що в MSDN зазначено наступне: "To disconnect a Recordset, open it with a cursor location of adUseClient, and then set the ActiveConnection property equal to Nothing. (C++ users should set the ActiveConnection equal to NULL to disconnect.)" , при спробі встановити ActiveConnection в NULL, отримую _com_error з текстом: "Аргументи є вгору типу, є з прийнятного рівня, або є в conflict with one another".

P.S. Чи дасть відключення connection реальний приріст у продуктивності? Чи можна використовувати Bacth Update не відключаючи connection?

А ви впевнені, що VT_EMPTY дорівнює NULL?

Яке ваше завдання я не зовсім зрозумів. Взагалі кажучи, використання BatchUpdate має бути викликано якимись серйозними причинами, якщо оновлення таке, що його не можна виконати простим запитом типу UPDATE, і особливо BatchUpdate — це не режим для використання кожну хвилину.

Я розумію фразу "(C++ users should set the ActiveConnection equal to NULL to disconnect.)" саме так, що VT_EMPTY = NULL (і те й інше = 0). Найцікавіше, що будь-яке інше значення (VT_NULL, VT_MISSING, просто NULL) викликає ту ж помилку.

Причина використання Batch Update в тому, що стоїть завдання з "перекачування" даних великих обсягів (Access DB від 10Mb і більше) на віддалений SQL Server. Я вже з'ясував, що використання Batch Update замість звичайного Insert/Update (для кожного окремого запису), дає приріст у продуктивності приблизно 40%. Єдине, що не вдається відключити connection (що, можливо, дасть ще якийсь приріст).

P.S. Але найцікавіше в тому, що утиліта DTS Import/Export із MS SQL Server із таким завданням справляється в рази швидше. Що вони там усередині використовують – чорт їх знає, але явно не ADO. OLE DB інтерфейси прямо чи що?

BULK INSERT воно використовує. І, можливо, лочить всю базу та встановлює на час RECOVERY у SIMPLE

Але BULK INSERT дозволяє просто вставити дані в таблицю з файлу з даними. Інша проблема в тому, що у мене завдання дещо ширше: як джерело/приймач даних можуть виступати будь-які data sources (MSSSQL, Access, Excel, CSV Files, XML Files і т.д.).

Ну, загалом, sergeax має рацію, DTS використовує BULK INSERT, але не той, що bcp.exe або BULK INSERT з TransactSQL, а недокументовану команду INSERT BULK, за якою слідує потік даних.

Так що на чому не пиши, швидкості DTS не досягнеш ;-)

Можна використовувати ODBC для читання джерел даних, скидати інформацію у файл, а потім закачувати їх у SQL Server за допомогою BULK INSERT. Можливо це і буде швидше за звичайні команди INSERT INTO…SELECT, але ось що набагато складніше — точно.

Якби все упиралося в просту трансофрмацію даних, то, звичайно, використовували б щось типу BULK INSERT. Але суть у тому, як я вже казав, що у нас вимога – підтримувати оновлення даних. А як це зробити крім як перевіряючи кожнузапис за значеннями primary key? Ось і виходить, що спочатку перевіряється наявність запису, а потім робиться або Insert або Update.

Тригер INSTEAD OF INSERT повинен працювати добре як за нормальної завантаження даних, і при BULK INSERT (якщо вказати опцію FIRE_TRIGGERS).

А що означає BatchUpdate та «відключення connection»? Що менше звернень відбувається до сервера, то краще. Тому всі зміни в базі даних проводити за одне звернення - підключився, виконав SQL-запит, вимкнувся.

Так, і чому C++? Завдання таке – на C++ писати?

Чому C++? Ну програми наші на C++ пишуться. ;-) Просто суть програми - робота з БД.

Пробував шукати з кількома перекладами "відключений" англійською, але ось "disconnected" пропустив. ;-) Дякую.