Access
 sql >> база данни >  >> RDS >> Access

Как Access общува с ODBC източници на данни? Част 2

АКТУАЛИЗИРАНЕ: Добавени са още някои пояснения около значението на SQLExecute и как Access обработва подготвените заявки. Благодаря, Боб!

Какво прави Access, когато преглеждаме и разглеждаме записи в ODBC свързана таблица?

Във втората част от нашата серия за проследяване на ODBC, фокусът ни ще се насочи към въздействието, което типовете набори от записи имат в рамките на ODBC свързана таблица. В последната статия научихме как да включим ODBC SQL трасиране и вече можем да видим изхода. Ако сте си поиграли малко с него, може би сте забелязали, че вашата заявка за Access и ODBC SQL изразите, които Access генерира, не изглеждат много сходни. Ние също така ще предоставим задълбочен поглед върху това как типовете влияят върху поведението на заявките SELECT и също така ще разгледаме различни варианти на набори от записи като моментни снимки и Dynasets.

Ако искате да следвате, можете да използвате примерната база данни, предоставена тук.

Ефект от типовете набори от записи в заявка SELECT

Типовете набори от записи имат голям ефект върху начина, по който Access ще комуникира с ODBC източниците на данни. Може да сте забелязали, че в изглед за проектиране на формуляр или в изглед за проектиране на заявка можете да зададете типа набор от записи. По подразбиране е настроен на Dynaset .

В VBA имаме още няколко опции, но засега няма да се тревожим за това. Нека започнем с разбирането какво точно Dynaset и Snapshot означава първо. Ще започнем с по-рядко използвания тип, Snapshot първо.

Набори от записи от тип моментна снимка

Snapshot е доста проста. Това основно означава, че правим моментна снимка на резултата в момента на изпълнение на заявката. Обикновено това също означава, че Access не може да актуализира резултата. Нека обаче да разгледаме как Access запитва източника с набор от записи, базиран на моментна снимка. Можем да създадем нова заявка за достъп по следния начин:

SQL, както можем да видим в SQL изгледа на заявката на Access е:

SELECT Cities.*
FROM Cities;
Ще изпълним заявката и след това ще разгледаме sqlout.txt файл. Ето изхода, форматиран за четливост:

SQLExecDirect:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
Имаше малко разлики между това, което написахме в заявката на Access, в сравнение с това, което Access изпрати до ODBC, което ще анализираме.

  1. Достъпът квалифицира таблицата с името на схемата. Очевидно в диалекта на Access SQL това не работи по същия начин, но за ODBC SQL диалект е полезно да се гарантира, че избираме от правилната таблица. Това се управлява от SourceTableName собственост.
  2. Достъпът разшири съдържанието на Cities.* в изброен списък с всички колони, за които Access вече знае въз основа на Fields колекция от основния TableDef обект.
  3. Достъпът използва " да цитират идентификаторите, което очаква ODBC SQL диалект. Въпреки че и Access SQL, и Transact-SQL използват скоби за цитиране на идентификатор, това не е законен синтаксис в диалекта на ODBC SQL.

Така че, въпреки че направихме само обикновена заявка за моментна снимка, избирайки всички колони за таблица, можете да видите, че Access извършва много трансформация на SQL между това, което сте поставили в изгледа за проектиране на заявка на Access или SQL изглед, спрямо това, което Access всъщност излъчва към данните източник. В този случай обаче той е предимно синтактичен, така че няма реална разлика в SQL израза между оригиналната заявка за Access и ODBC SQL израза.

Проследяването също добави SQLExecDirect в началото на SQL израза. Ще се върнем към това, след като разгледаме няколко други примера.

Набори от записи от типа Dynaset

Ще използваме същата заявка, но ще променим свойството обратно до неговото по подразбиране, Dynaset .
Стартирайте го отново и ще видим какво получаваме от sqlout.txt . Отново е форматиран за четливост:

SQLExecDirect:
SELECT
  "Application"."Cities"."CityID"
FROM "Application"."Cities"

SQLPrepare:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
WHERE "CityID" = ?

SQLExecute: (GOTO BOOKMARK)

SQLPrepare:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
WHERE "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)
Уау, много неща се случват! Това определено е по-бъбриво от записите от типа на моментна снимка. Нека ги разгледаме един по един.

Първият избира само CityID колона. Това се оказва основният ключ на таблицата, но по-важното е, че това е индексът, който Access използва от своя страна. Това ще стане важно, когато изучаваме изгледите по-късно. Access използва тази заявка, за да получи ключовете и да я използва за попълване на други заявки по-късно, както ще видим.

Вторият израз е по-близо до оригиналната заявка за моментна снимка, с изключение на това, че вече имаме ново WHERE филтриране на клауза в CityID колона. От това можем да видим, че това е едноредово извличане. Можем да използваме ключовете, които получихме от първата заявка, и да съберем останалите колони в тази заявка. Всеки път, когато това подготвено изявление се изпълни, ще видите SQLExecute: (GOTO BOOKMARK) .

Но това би било неефективно, ако трябваше да направим това за всички редове... И тук идва следващата заявка. Третият израз е подобен на втория, но има 10 предиката. Тази подготвена заявка се изпълнява с всяко SQLExecute: (MULTI_ROW FETCH) . Това означава, че когато заредим формуляр или лист с данни или дори отворим набор от записи във VBA код, Access ще използва или версията с един ред, или версията с няколко реда и ще попълни параметрите, използвайки ключовете, които получи от първия заявка.

Извличане на фон и повторно синхронизиране

Между другото, забелязвали ли сте някога как когато отворите формуляр или лист с данни, не можете да видите „X от Y“ в лентата за навигация?

Това е, защото Access не може да знае колко има, докато не приключи събирането на резултатите от първата заявка. Ето защо често може да откриете, че е много бързо да отворите заявка, която връща голямо количество данни. Преглеждате само малък прозорец от целия набор от записи, докато Access извлича редовете във фонов режим. Ако щракнете върху бутона „Отиди до последно“, тогава може да откриете, че той блокира достъпа. Ще трябва да изчакате, докато завърши извличането на всички ключове в първата заявка, преди да можем да видим „X от Y“ в лентата за навигация.

По този начин можете да оцените как Access може да създаде илюзията за бързо отваряне дори на голям набор от записи, когато използваме набор от записи от dynaset и това обикновено е добро изживяване за потребителя.

И накрая, трябва да отбележим, че имаме 3 различни типа изпълнения, SQLExecDirect , SQLPrepare и SQLExecute . Виждате, че с първия нямаме никакви параметри. Заявката е просто такава, каквато е. Въпреки това, ако една заявка трябва да бъде параметризирана, тя трябва първо да бъде подготвена чрез SQLPrepare и след това се изпълнява по-късно с SQLExecute с предоставени стойности за параметри. Не можем да видим какви стойности всъщност са били предадени в SQLExecute изявление, въпреки че можем да заключим от това, което виждаме в Access. Можете да знаете само дали е извадил един ред (с помощта на SQLExecute: (GOTO BOOKMARK) или няколко реда (с помощта на SQLExecute: (MULTI-ROW FETCH) ). Access ще използва версията с няколко реда, за да извърши фоново извличане и постепенно да попълни набора от записи, но ще използва версията с един ред, за да попълни само един ред. Това може да е така в един изглед на формуляр, за разлика от непрекъснат изглед на формуляр или лист с данни или да го използвате за повторно синхронизиране след актуализация.

Навигиране наоколо

С достатъчно голям набор от записи, Access може да не успее да завърши извличането на всички записи. Както беше отбелязано по-горе, на потребителя се представят данните възможно най-скоро. Обикновено, когато потребителят се придвижва напред през набора от записи, Access ще продължи да извлича все повече и повече записи, за да поддържа буфера пред потребителя.

Но да предположим, че потребителят прескача до 100-ия ред, като отиде в контрола за навигация и въведе 100 там?

В този случай Access ще изпрати следните заявки...

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (GOTO BOOKMARK)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)
Обърнете внимание как Access използва вече подготвените оператори, които е създал в момента на отваряне на набора от записи. Тъй като вече има ключовете от първата заявка, той може да знае кой е „100-ият“ ред. Да използвам по-конкретен пример. Да предположим, че имаме CityID като се започне от 1, 3, 4, 5…99, 100, 101, 102 без запис за CityID = 2 . В първата заявка CityID 101 ще бъде на 100-ия ред. Следователно, когато потребителят прескочи до 100, Access търси 100-ия ред в първата заявка, вижте, че това е CityID 101, след което приема тази стойност и я подава в SQLExecute: (GOTO BOOKMARK) за незабавно навигиране към този запис. След това разглежда следващите 10 записа и използва тези последващи CityID за запълване на буфера с множество SQLExecute: (MULTI-ROW FETCH) . Може да сте забелязали, че има извличане на няколко реда преди извличане на един ред. Access всъщност извлича 101-ия-110-ия ред в извличането на множество редове и извлича 100-ия запис при следващото извличане на единичен ред.

След като Access получи данните за редовете на 100-ия, той отвежда потребителя там, след което започнете да попълвате буфера около този 100-ти ред. Това позволява на потребителя да види 100-ия ред, без да се налага да чака за зареждане на всички записи от 11-99. Потребителят също има очевидно бързо изживяване при сърфиране, когато потребителят щракне предишно или следващо от новата позиция, тъй като Access вече го е заредил на заден план, преди потребителят да го поиска. Това помага да се създаде илюзията, че сте бърз дори в бавна мрежа.

Но дори ако потребителят остави формуляра отворен и неактивен, Access ще продължи да извършва както фоново извличане, така и опресняване на буфера, за да избегне показването на остарели данни на потребителя. Това се управлява от настройките на ODBC в диалоговия прозорец Опции, в раздела Разширени в раздела Настройки на клиента:

По подразбиране за интервала за опресняване на ODBC е 1500 секунди, но може да се промени. Може също да се промени чрез VBA.

Заключения:тънък или бъбрив

Сега трябва да видите, че основната причина, поради която наборите от записи от типа dynaset могат да се актуализират, но наборите от записи от типа моментна снимка не, е, че Access може да замени ред в набора от записи с най-новата версия на същото от сървъра, тъй като знае как да избере един ред. Поради тази причина Access трябва да управлява 2 ODBC заявки; един за извличане на ключовете и друг за извличане на действителното съдържание на редове за даден ключ. Тази информация не присъстваше с набор от записи от типа моментна снимка. Току-що получихме голям блок от данни.

Разгледахме 2 основни типа записи, въпреки че има повече. Други обаче са само варианти на 2-та вида, които разгледахме. Но засега е достатъчно да запомните, че използването на моментна снимка означава да бъдете натрупани в нашата мрежова комуникация. От друга страна, да използваме dynaset означава, че ще бъдем бъбриви. И двете имат своите възходи и падения.

Например, наборът от записи за моментни снимки не се нуждае от допълнителна комуникация със сървъра, след като извлече данните. Докато наборът от записи остава отворен, Access може свободно да навигира из своя локален кеш. Достъпът също не трябва да поддържа никакви ключалки и по този начин да блокира други потребители. Въпреки това наборът от записи за моментни снимки по необходимост се отваря по-бавно, тъй като трябва да събере всички данни предварително. Това може да не е подходящо за голям набор от записи, дори ако възнамерявате да прочетете всички данни.

Да предположим, че създавате голям отчет за Access, който е от 100 страници, обикновено си струва да използвате набор от записи от dynaset. Може да започне да изобразява визуализацията веднага щом има достатъчно за изобразяване на първата страница. Това е по-добре, отколкото да ви принуждавате да чакате, докато извлече всички данни, преди да започне да изобразява визуализацията. Въпреки че наборът от записи на dynaset може да приеме заключвания, обикновено това е за кратко време. Той е достатъчно дълъг, за да може Access да синхронизира повторно своя локален кеш.

Но когато помислим колко повече заявки изпраща Access по мрежата с набор от записи от тип dynaset, е лесно да видим, че ако латентността на мрежата е лоша, производителността на Access ще пострада съответно. За да може Access да позволи на потребителите да редактират и актуализират източници на данни по общ начин, изисква Access да следи ключовете за избор и промяна на един ред. Ще разгледаме това в следващите статии. В следващата статия ще разгледаме как сортирането и групите влияят на набор от записи от тип dynaset, както и как Access определя ключа, който да се използва за набор от записи от тип dynaset.

За повече помощ с Microsoft Access, обадете се на нашите експерти на 773-809-5456 или ни изпратете имейл на [email protected].


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на навигация само с клавиатура в Word, Excel и PowerPoint (Част 2:Диалогови кутии)

  2. Топ 7 бази данни

  3. Слушайте подкаста на Microsoft Access, епизод 1

  4. Базов клас VBA и производен обект-2

  5. Как да отстраните 10 проблема с Common Access 2019