Access
 sql >> Baza danych >  >> RDS >> Access

Jak program Access komunikuje się ze źródłami danych ODBC? Część 6

Efekt złączeń w zestawie rekordów

W naszym szóstym i ostatnim artykule z serii śledzenia ODBC przyjrzymy się, jak program Access będzie obsługiwał sprzężenia w zapytaniach programu Access. W poprzednim artykule widziałeś, jak program Access obsługuje filtry. W zależności od wyrażenia program Access może zdecydować się na jego sparametryzowanie lub może być zmuszony do samodzielnej oceny przez pobranie wszystkich danych wejściowych, a następnie wykonanie oceny lokalnie. W tym artykule skupimy się na złączeniach. Kiedy się nad tym zastanowić, złączenia są w rzeczywistości specjalnym rodzajem filtra. Dlatego teoretycznie Access powinien być jak najbardziej zdalny, nawet przy łączeniu. Zwykle możesz zobaczyć złączenia napisane w następującym pseudo-SQL:

OD WEWNĘTRZNEGO ZŁĄCZENIA b NA a.ID =b.ID
Można go jednak uznać za równoważny następującej składni:

OD a, b GDZIE a.ID =b.ID
To ilustruje, że chociaż możemy użyć bardziej czytelnego i znanego JOIN..ON , Access może bezpłatnie traktować go jako WHERE co jest przydatne w sytuacjach, gdy program Access nie może w pełni zdalnie wykonać zapytania. Ale sęk w tym… kiedy Access decyduje się na zdalne połączenie? Wypróbujmy proste zapytanie sprzężenia:

SELECT c.CityID ,c.StateProvinceID ,c.StateProvinceID ,s.StateProvinceNameFROM Cities AS c INNER JOIN StanProwincje AS s ON c.StateProvinceID =s.StateProvinceID;
Jeśli prześledzimy to zapytanie, zobaczymy następujący wynik:

SQLExecDirect:SELECT "c"."CityID" ,"s"."StateProvinceID" FROM "Application"."Miasta" "c", "Application"."StateProvinces" "s" WHERE ("c"." StateProvinceID" ="s"."StateProvinceID" ) SQLPrepare:SELECT "CityID" ,"CityName" ,"StateProvinceID" FROM "Aplikacja"."Miasta" WHERE "CityID" =?SQLExecute:(GOTO BOOKMARK)SQLPrepare:SELECT "StateProvinceID" " ,"StateProvinceName" FROM "Application"."StateProvinces" WHERE "StateProvinceID" =?SQLExecute:(GOTO ZAKŁADKA)SQLPrepare:SELECT "StateProvinceID" ,"StateProvinceName" FROM "Application"."StateProvinces"?vinceID "StateProvince" LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? LUB "Identyfikator Województwa Stanu" =? OR "StateProvinceID" =?SQLExecute:(MULTI-ROW FETCH)SQLPrepare:SELECT "CityID" ,"CityName" ,"StateProvinceID" FROM "Application"."Miasta" WHERE "CityID" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "CityID" =?SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(MULTI - ROW FETCH) SQLExecute:(WIELO ROW FETCH) SQLExecute:(WIELO ROW FETCH) SQLExecute:(WIELO ROW FETCH)
Access zdecydował, że nie będzie zdalnym sprzężeniem, mimo że oryginalne zapytanie Access jest w pełni możliwe do wykonania w SQL Server. Zamiast tego pobierał identyfikatory z każdej tabeli w połączeniu theta, a następnie ustawiał 2 oddzielne łańcuchy zapytań, tak jakbyśmy otworzyli 2 zestawy rekordów typu dynaset. Do dwóch różnych przygotowanych zapytań są następnie wprowadzane klucze dla odpowiednich tabel z pierwszego zapytania. Przewidywalnie, może to być dużo gadania w sieci.

Jeśli zmienimy to samo zapytanie Access na typ migawki zamiast domyślnego typu dynaset, otrzymamy:

SQLExecDirect:SELECT "c"."Identyfikator miasta" ,"c"."Nazwa miasta" ,"c"."IDProwincjiState" ,"s"."NazwaProwincjiState" FROM "Aplikacja"."Miasta" "c", " Application"."StateProvinces" "s" WHERE ("c"."StateProvinceID" ="s"."StateProvinceID" )
Tak więc program Access zdalnie łączy sprzężenia dobrze w przypadku kwerendy typu migawka. Dlaczego program Access nie zrobił tego z oryginalnym zapytaniem typu Dynaset? Wskazówka znajduje się na poniższym zrzucie ekranu, na którym próbujemy edytować oba kolumny tabel na poniższym zrzucie ekranu:

Takie zapytanie umożliwia aktualizację do obu kolumn. W rzeczywistości nie jest to możliwe do wyrażenia w SQL, ale takie działanie jest dozwolone dla użytkownika. W związku z tym, aby wykonać tę aktualizację, program Access prześle następujący kod ODBC SQL:

SQLExecDirect:UPDATE "Aplikacja". "StateProvinces" SET "StateProvinceName"=? GDZIE "StateProvinceID" =? AND "StateProvinceName" =?SQLExecDirect:UPDATE "Aplikacja"."Miasta" SET "CityName"=? GDZIE "Identyfikator Miasta" =? ORAZ "Nazwa Miasta" =? ORAZ „Identyfikator prowincji” =?
Nie byłoby to możliwe, gdyby program Access nie dysponował informacjami wymaganymi do zaktualizowania każdej tabeli, co wyjaśnia, dlaczego program Access nie zdecydował się na zdalne sprzężenie podczas rozwiązywania oryginalnego zapytania typu zestaw dynamiczny. Lekcja z tego jest taka, że ​​jeśli nie potrzebujesz aktualizacji zapytania, a wynikowe dane są wystarczająco małe, może być lepiej przekonwertować zapytanie na typ migawki. W przypadku, gdy musisz sformułować złożone źródło rekordów, zwykle uzyskasz znacznie lepszą wydajność, używając widoku SQL jako podstawy, niż robiąc złączenia po stronie Access.

Aby to udowodnić, utworzymy widok SQL i połączymy go z programem Access:

UTWÓRZ WIDOK dbo.vwCitiesAndStates ASSELECT c.CityID ,c.StateProvinceID ,c.CityName ,s.StateProvinceNameFROM Application.Cities AS c INNER JOIN Application.StateProvinces AS s ON c.StateProvinceID =s.StateProvinceID> 
SELECT c.IDMiasta ,c.IdentyfikatorProwincji Stanu ,c.NazwaMiasta ,c.NazwaProwincjistanuFROM vwCitiesAndStates AS c;
Jeśli następnie powtórzymy aktualizację, której próbowaliśmy pierwotnie, powinniśmy zobaczyć następujący śledzony SQL ODBC:

SQLExecDirect:SELECT "c"."CityID" FROM "dbo"."vwCitiesAndStates" "c" SQLPrepare:SELECT "CityID" ,"StateProvinceID" ,"CityName" ,"StateProvinceName"FROM "dbo"."vwCitiesAndStates" WHERE "CityID" =?SQLExecute:(GOTO ZAKŁADKA)SQLPrepare:SELECT "CityID" , "StateProvinceID" ,"CityName" ,"StateProvinceName" FROM "dbo"."vwCitiesAndStates" WHERE "CityID" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "Identyfikator Miasta" =? LUB "CityID" =?SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(FETCH MULTI-ROW)SQLExecute:(GOTO ZAKŁADKA) SQLExecDirect:UPDATE "dbo". "vwCitiesAndStates" SET "CityName"=?, "StateProvinceName"=? GDZIE "Identyfikator Miasta" =? ORAZ „Identyfikator Województwa Stanu” =? ORAZ "Nazwa Miasta" =? ORAZ „StateProvinceName” =?
Pokazuje to, że używając widoków SQL do „zdalnego” łączenia, program Access będzie działał tylko z jednym źródłem, a nie z 2 tabelami i zdalną aktualizację widoku w pełni do SQL Server. Jednym ze skutków ubocznych jest to, że ta aktualizacja zakończy się niepowodzeniem i wyświetleniem komunikatu o błędzie:

Nie powinno to dziwić, ponieważ przeprowadzaliśmy UPDATE na jednym źródle, podczas gdy w oryginalnym przykładzie program Access potajemnie wydawał dwa oddzielna UPDATE oświadczenia na każdym indywidualnym stole. Mamy nadzieję, że pomoże to w stwierdzeniu, że należy unikać łączenia w zapytaniach/źródłach rekordów/źródłach wierszy programu Access, zwłaszcza gdy muszą być aktualizowane. Jeśli nie, użyj migawki, jeśli to możliwe.

Krótka uwaga na temat połączeń heterogenicznych

Musimy skomentować połączenia między dwiema połączonymi tabelami, które pochodzą z dwóch różnych źródeł danych ODBC. Takie sprzężenia są „heterogeniczne”, ponieważ program Access musi obsługiwać sprzężenia lokalnie, ponieważ zakłada się, że każde ze źródeł danych nie zna się nawzajem. Niezależnie od tego, czy określono zestaw rekordów typu zestaw dynamiczny, czy zestaw rekordów typu migawka, program Access musi pobrać pełny zestaw kluczy z każdego źródła danych i rozwiązać sprzężenia, wysyłając oddzielne sparametryzowane zapytania do każdego źródła danych. Jeśli aktualizacja jest dozwolona, ​​program Access sformułuje oddzielną UPDATE zapytanie do każdego źródła danych, które należy zaktualizować. Należy również zauważyć, że połączenie między dwiema połączonymi tabelami, które pochodzą z dwóch różnych baz danych, jest nadal uważane przez program Access za heterogeniczne. Jest to nadal prawdziwe, nawet jeśli dwie bazy danych znajdują się na tym samym serwerze i nie masz problemu z wykonywaniem zapytań między bazami danych. W tym scenariuszu widok SQL może pomóc w ograniczeniu dodatkowego gadania, ukrywając sprzężenia między bazami danych w programie Access, podobnie jak to widzieliśmy już w tym artykule.

Różnica składni złączenia zewnętrznego

Dopóki sprzężenia zewnętrzne nie wpływają na możliwość aktualizacji kwerendy programu Access, program Access obsłuży ją podobnie do sposobu obsługi wersji sprzężenia wewnętrznego. Jeśli zmodyfikujemy to samo zapytanie, które było sprzężeniem lewym, śledzony SQL ODBC wygeneruje zapytanie o wypełnienie klucza w następujący sposób:

SQLExecDirect:SELECT "c"."CityID" ,"s"."StateProvinceID" FROM {oj "Aplikacja"."Miasta" "c" LEWE ZŁĄCZENIE ZEWNĘTRZNE "Aplikacja"."StateProvinces" "s" ON (" c"."StateProvinceID" ="s"."StateProvinceID" ) }
Składnia wygląda zupełnie inaczej niż w innych dialektach SQL. Dzieje się tak, ponieważ gramatyka ODBC SQL wymaga, aby każde złącze zewnętrzne było opakowane w {oj ...} wyrażenie. Aby uzyskać więcej informacji na temat tej składni, zapoznaj się z dokumentacją. Dla naszych celów możemy po prostu zignorować {oj i zamykający } jako hałas.

Wnioski

Widzieliśmy, że sprzężenia są traktowane tak, jakby były rodzajem filtra, a program Access będzie próbował je zdalnie odłączyć tam, gdzie jest to dozwolone. Szczególnym obszarem, na który należy zwrócić szczególną uwagę, jest fakt, że domyślnie używamy zestawów rekordów typu dynaset, a program Access nie będzie robił żadnych założeń dotyczących tego, czy chcemy zezwolić na modyfikowanie takich a takich kolumn w zestawie rekordów i robi wszystko, aby nam to umożliwić zaktualizować do dwóch tabel, co w rzeczywistości nie jest łatwe do wyrażenia w standardowym SQL. W rezultacie program Access wykona znacznie więcej pracy, aby zapewnić możliwość aktualizacji zapytania zawierającego sprzężenia, które mogą negatywnie wpłynąć na wydajność.

Możemy pomóc uniknąć kary, używając widoków SQL zamiast sprzężeń wyrażonych w zapytaniu programu Access. Kompromis polega na tym, że podlegamy wtedy regułom aktualizowalności widoku SQL; możemy nie mieć możliwości jednoczesnego aktualizowania dwóch tabel. Zwykle, ponieważ dobrze zaprojektowany formularz Access będzie reprezentował tylko jedną tabelę do aktualizacji, nie stanowi to dużego ograniczenia i jest dobrą dyscypliną do przestrzegania.

Na tym kończy się obecna seria. Jednak nie należy uczyć się, że seria, miejmy nadzieję, iskrzy. Mam szczerą nadzieję, że seria ta okazała się przydatna i czekamy na informacje o nowych spostrzeżeniach uzyskanych dzięki użyciu narzędzi pomagających analizować i rozwiązywać problemy z wydajnością w aplikacjach Access korzystających ze źródeł danych ODBC. Zachęcamy do zostawiania komentarzy lub prośby o więcej informacji i dziękujemy za wspólne czytanie!

Aby uzyskać dalszą pomoc we wszystkim, co jest związane z Microsoft Access, zadzwoń do naszych ekspertów pod numer 773-809-5456 lub wyślij e-mail na adres [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. Powody, dla których warto zmienić aplikacje Access w aplikacje internetowe

  2. ROZWIĄZANE:Microsoft Office 365 w wersji 2009 może uszkodzić aplikację bazy danych

  3. Jakie są zalety systemu zarządzania danymi?

  4. Jak dodać nagłówek i stopkę do raportu w programie Microsoft Access

  5. 5 wskazówek dotyczących zarządzania zespołami podczas dystansu społecznego