Деактивиран набор от записи на ADO
Моля, предоставете пример (за предпочитане на C++), който създава и използва "деактивиран" набор от записи с помощта на ADO.
Отговорено: 12
Хм. Не толкова просто.
--- // задайте свойството "локация на курсора" spTargetRecordset->PutCursorLocation(ADO: :adUseClient); // отваряне на набор от записи spTargetRecordset->Open(bstrTTableName, _variant_t((IDispatch*)dbconn.m_spConnection), ADO::adOpenStatic, ADO::adLockBatchOptimistic, (long)ADO::adCmdTable); // опитайте се да прекъснете връзката с набор от записи spTargetRecordset->PutActiveConnection(V T_EMPTY); ---
Въпреки че MSDN казва „За да прекъснете връзката с Recordset, отворете го с местоположение на курсора на adUseClient и след това задайте свойството ActiveConnection равно на Nothing. (Потребителите на C++ трябва да зададат ActiveConnection равно на NULL, за да прекъснат връзката.)“, когато се опитам да задам ActiveConnection на NULL, получавам _com_error с текст: „Аргументите са от грешен тип, са извън допустимия диапазон или са в конфликт един с друг“.
P.S. Деактивирането на връзката ще даде ли реално увеличение на производителността? Или е възможно да използвате Bacth Update, без да прекъсвате връзката?
Сигурни ли сте, че VT_EMPTY е NULL?
Каква е твоята задача, не разбрах съвсем. Най-общо казано, трябва да има някаква основателна причина да се използва BatchUpdate, ако актуализацията е такава, че не може да се направи с проста заявка от типа UPDATE, и още повече, че BatchUpdate не е режим, който да се използва всяка минута.
Разбирам, че фразата „(Потребителите на C++ трябва да зададат ActiveConnection равно на NULL, за да прекъснат връзката.)“ означава точно, че VT_EMPTY = NULL (и двете = 0). Най-интересното е, че всяка друга стойност (VT_NULL, VT_MISSING, просто NULL) причинява същата грешка.
Причината за използването на пакетна актуализация е, че задачата е да се "изпомпват" големи обеми данни (достъп до DB от 10Mb и повече) към отдалечен SQL сървър. Вече разбрах, че използването на пакетна актуализация вместо обичайното вмъкване / актуализация (за всеки отделен запис) дава увеличение на производителността с около 40%. Единственото нещо, което не успява, е да "прекъснете" връзката (което може би ще даде повече печалба).
P.S. Но най-интересното е, че помощната програма DTS Import / Export от MS SQL Server се справя с тази задача многократно по-бързо. Какво използват вътре - дявол знае, но явно не ADO. OLE DB интерфейси директно или какво?
BULK INSERT използва. И, вероятно, заключва цялата база данни и задава ВЪЗСТАНОВЯВАНЕ на ПРОСТО за известно време
Но BULK INSERT ви позволява просто да вмъкнете данни в таблица от файл с данни. Друг проблем е, че моята задача е малко по-широка: всякакви източници на данни (MSSSQL, Access, Excel, CSV файлове, XML файлове и т.н.) могат да действат като източник на данни / дестинация.
Е, като цяло, sergeax е прав, DTS използва BULK INSERT, но не този bcp.exe или BULK INSERT от TransactSQL, а недокументирана команда INSERT BULK, последвана от поток от данни.
Така че каквото и да пишеш няма да достигнеш DTS скорост ;-)
Можете да използвате ODBC, за да четете източници на данни, да изхвърляте информацията във файл и след това да я качите на SQL Server с помощта на BULK INSERT. Може би това ще бъде по-бързо от обичайните команди INSERT INTO ... SELECT, но ето какво е много по-сложно - със сигурност.
Ако всичко опираше до проста трансформация на данни, тогава, разбира се, те биха използвали нещо като BULK INSERT. Но най-важното е, както казах, че имаме изискване да поддържаме данните актуализирани. И как да го направите, освен като проверите всекизапис по стойности на първичен ключ? Така се оказва, че първо се проверява съществуването на записа и след това се прави или Insert, или Update.
Тригер INSTEAD OF INSERT трябва да работи добре както за нормално зареждане на данни, така и за BULK INSERT (ако посочите опцията FIRE_TRIGGERS).
И какво означава BatchUpdate и "disconnect connection"? Колкото по-малко обаждания към сървъра, толкова по-добре. Следователно всички промени в базата данни трябва да се правят в едно извикване - свързване, изпълнение на SQL заявка, прекъсване на връзката.
Да, и защо в C++? Задачата е това - да пиша на C++?
Защо в C++? Е, нашите приложения са написани на C++. ;-) Просто същността на приложението е работата с базата данни.
Опитах се да търся с няколко превода на „прекъснат“ на английски, но пропуснах „прекъснат“. ;-) Благодаря ви.