Access
 sql >> Teknologi Basis Data >  >> RDS >> Access

Bagaimana Access berbicara dengan sumber data ODBC? Bagian 6

Efek penggabungan dalam kumpulan rekaman

Dalam artikel keenam dan terakhir kami dari seri penelusuran ODBC, kami akan melihat bagaimana Access akan menangani gabungan dalam kueri Access. Di artikel sebelumnya, Anda melihat bagaimana filter ditangani oleh Access. Bergantung pada ekspresi, Access dapat memilih untuk membuat parameternya atau mungkin dipaksa untuk mengevaluasinya sendiri dengan mengunduh semua data input lalu melakukan evaluasi secara lokal. Pada artikel ini, kita akan fokus pada bergabung. Ketika Anda memikirkannya, bergabung sebenarnya adalah jenis filter khusus. Oleh karena itu, secara teori, Access harus melakukan remote sebanyak mungkin bahkan dengan join. Anda mungkin biasanya melihat gabungan yang ditulis dalam pseudo-SQL berikut:

FROM a INNER JOIN b ON a.ID = b.ID
Namun, ini dapat dianggap setara dengan sintaks berikut:

FROM a, b WHERE a.ID = b.ID
Itu menggambarkan bahwa meskipun kita mungkin menggunakan JOIN..ON yang lebih mudah dibaca dan familiar , Access bebas memperlakukannya sebagai WHERE yang berguna dalam situasi di mana Access tidak dapat sepenuhnya membuat kueri jauh. Tapi inilah masalahnya… kapan Access memutuskan untuk melakukan remote join? Mari kita coba kueri bergabung sederhana:

SELECT 
   c.CityID
  ,c.StateProvinceID
  ,c.CityName
  ,s.StateProvinceName
FROM Cities AS c 
INNER JOIN StateProvinces AS s 
  ON c.StateProvinceID = s.StateProvinceID;
Jika kita menelusuri query tersebut, kita akan melihat output berikut:

SQLExecDirect: 
SELECT 
   "c"."CityID"
  ,"s"."StateProvinceID" 
FROM "Application"."Cities" "c",
     "Application"."StateProvinces" "s" 
WHERE ("c"."StateProvinceID" = "s"."StateProvinceID" ) 

SQLPrepare: 
SELECT 
  "CityID"
 ,"CityName"
 ,"StateProvinceID"  
FROM "Application"."Cities"  
WHERE "CityID" = ?

SQLExecute: (GOTO BOOKMARK)

SQLPrepare: 
SELECT 
   "StateProvinceID"
  ,"StateProvinceName"  
FROM "Application"."StateProvinces"  
WHERE "StateProvinceID" = ?

SQLExecute: (GOTO BOOKMARK)

SQLPrepare: 
SELECT 
   "StateProvinceID"
  ,"StateProvinceName"  
FROM "Application"."StateProvinces"  
WHERE "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ? 
   OR "StateProvinceID" = ?

SQLExecute: (MULTI-ROW FETCH)

SQLPrepare: 
SELECT 
   "CityID"
  ,"CityName"
  ,"StateProvinceID"  
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)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)
Access memutuskan untuk tidak menggabungkan jarak jauh, meskipun kueri Access asli mampu dieksekusi dengan sempurna di SQL Server. Sebagai gantinya, ia mendapatkan ID dari setiap tabel dalam theta-join, lalu menyiapkan 2 rantai kueri terpisah seolah-olah kita telah membuka 2 kumpulan rekaman tipe dynaset. Dua kueri yang disiapkan berbeda kemudian diberi kunci untuk masing-masing tabel dari kueri pertama. Bisa ditebak, itu bisa menjadi banyak obrolan untuk melewati jaringan.

Jika kita mengubah kueri Access yang sama menjadi tipe snapshot alih-alih tipe dynaset default, kita mendapatkan:

SQLExecDirect: 
SELECT 
   "c"."CityID"
  ,"c"."CityName"
  ,"c"."StateProvinceID"
  ,"s"."StateProvinceName"  
FROM "Application"."Cities" "c",
     "Application"."StateProvinces" "s" 
WHERE ("c"."StateProvinceID" = "s"."StateProvinceID" )
Jadi Access melakukan penggabungan jarak jauh dengan baik dalam kasus kueri tipe snapshot. Mengapa Access tidak melakukannya dengan kueri tipe-dinaset asli? Petunjuknya ada di tangkapan layar berikut tempat kami mencoba mengedit keduanya kolom tabel pada tangkapan layar berikut:

Kueri semacam itu memungkinkan pembaruan ke kedua kolom. Itu sebenarnya tidak dapat diekspresikan dalam SQL tetapi tindakan seperti itu legal untuk dilakukan pengguna. Oleh karena itu, untuk menjalankan pembaruan tersebut, Access akan mengirimkan SQL ODBC berikut:

SQLExecDirect: 
UPDATE "Application"."StateProvinces" 
SET "StateProvinceName"=?  
WHERE "StateProvinceID" = ? 
  AND "StateProvinceName" = ?

SQLExecDirect: 
UPDATE "Application"."Cities" 
SET "CityName"=?  
WHERE "CityID" = ? 
  AND "CityName" = ? 
  AND "StateProvinceID" = ?
Itu tidak akan mungkin jika Access tidak memiliki informasi yang diperlukan untuk memperbarui setiap tabel, yang menjelaskan mengapa Access memilih untuk tidak menggabungkan jarak jauh saat menyelesaikan kueri tipe dynaset asli. Pelajaran di sini adalah bahwa jika Anda tidak memerlukan kueri untuk dapat diperbarui, dan data yang dihasilkan cukup kecil, mungkin lebih baik untuk mengubah kueri menjadi jenis snapshot. Dalam kasus di mana Anda perlu merumuskan sumber rekaman yang kompleks, Anda biasanya akan mendapatkan kinerja yang jauh lebih baik menggunakan tampilan SQL sebagai basis daripada melakukan penggabungan di sisi Access.

Untuk membuktikan ini, kami akan membuat tampilan SQL dan menautkannya ke Access:

CREATE VIEW dbo.vwCitiesAndStates AS
SELECT 
  c.CityID
  ,c.StateProvinceID
  ,c.CityName
  ,s.StateProvinceName
FROM Application.Cities AS c 
INNER JOIN Application.StateProvinces AS s 
  ON c.StateProvinceID = s.StateProvinceID;
Kami kemudian menyesuaikan kueri Access sebagai berikut:

SELECT 
   c.CityID
  ,c.StateProvinceID
  ,c.CityName
  ,c.StateProvinceName
FROM vwCitiesAndStates AS c;
Jika kemudian kami mengulangi pembaruan yang kami coba sebelumnya, kami akan melihat ODBC SQL yang dilacak berikut ini:

SQLExecDirect: 
SELECT "c"."CityID" 
FROM "dbo"."vwCitiesAndStates" "c" 

SQLPrepare: 
SELECT 
   "CityID"
  ,"StateProvinceID"
  ,"CityName"
  ,"StateProvinceName"  
FROM "dbo"."vwCitiesAndStates"  
WHERE "CityID" = ?

SQLExecute: (GOTO BOOKMARK)

SQLPrepare: 
SELECT 
   "CityID"
  ,"StateProvinceID"
  ,"CityName"
  ,"StateProvinceName"  
FROM "dbo"."vwCitiesAndStates"  
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)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (GOTO BOOKMARK)

SQLExecDirect: 
UPDATE "dbo"."vwCitiesAndStates" 
SET "CityName"=?,
    "StateProvinceName"=?  
WHERE "CityID" = ?
  AND "StateProvinceID" = ?
  AND "CityName" = ? 
  AND "StateProvinceName" = ?
Hal ini menunjukkan bahwa menggunakan tampilan SQL untuk "menjauhkan" gabungan, Access hanya akan bekerja dengan satu sumber, bukan dengan 2 tabel dan memperbarui tampilan sepenuhnya ke SQL Server dari jarak jauh. Satu efek sampingnya adalah pembaruan ini sekarang akan gagal dengan pesan kesalahan:

Itu seharusnya tidak mengejutkan karena kami melakukan UPDATE pada satu sumber sedangkan dalam contoh aslinya, Access sebenarnya secara diam-diam mengeluarkan dua pisahkan UPDATE pernyataan pada setiap tabel individu. Mudah-mudahan itu membantu membuat kasus bahwa Anda harus menghindari melakukan penggabungan dalam kueri/sumber rekaman/sumber baris Access terutama ketika mereka harus dapat diperbarui. Jika tidak, gunakan snapshot jika memungkinkan.

Catatan singkat tentang gabungan heterogen

Kami perlu berkomentar mengenai gabungan antara dua tabel tertaut yang berasal dari dua sumber data ODBC yang berbeda. Gabungan tersebut bersifat “heterogen” karena Access harus menangani gabungan tersebut secara lokal karena setiap sumber data dianggap tidak saling mengenal. Terlepas dari apakah Anda menentukan kumpulan catatan tipe dynaset atau tipe snapshot, Access harus mengambil kumpulan kunci lengkap dari setiap sumber data dan menyelesaikan gabungan dengan mengirimkan kueri berparameter terpisah ke setiap sumber data. Jika pembaruan diizinkan, Access akan merumuskan UPDATE yang terpisah kueri ke setiap sumber data yang perlu diperbarui. Penting juga untuk dicatat bahwa gabungan antara dua tabel tertaut yang berasal dari dua database berbeda masing-masing masih dianggap oleh Access sebagai heterogen. Itu masih benar bahkan jika dua database berada di server yang sama dan Anda tidak memiliki masalah melakukan kueri lintas database. Dalam skenario ini, tampilan SQL dapat membantu mengurangi obrolan tambahan dengan menyembunyikan gabungan database silang dari Access serupa dengan yang sudah kita lihat di artikel ini.

Perbedaan sintaks gabungan luar

Selama gabungan luar tidak memengaruhi pembaruan kueri Access, Access akan menanganinya dengan cara yang sama seperti menangani versi gabungan dalam. Jika kita memodifikasi kueri yang sama dengan yang digunakan sebagai gabungan kiri, ODBC SQL yang dilacak akan menampilkan kueri populasi kunci seperti ini:

SQLExecDirect: 
SELECT 
   "c"."CityID"
  ,"s"."StateProvinceID" 
FROM {oj 
	"Application"."Cities" "c" 
	LEFT OUTER JOIN "Application"."StateProvinces" "s" 
		ON ("c"."StateProvinceID" = "s"."StateProvinceID" ) 
}
Sintaksnya terlihat sangat berbeda dari apa yang Anda harapkan dalam dialek SQL lainnya. Itu karena tata bahasa SQL ODBC mengharuskan setiap gabungan luar dibungkus dengan {oj ...} ekspresi. Untuk detail selengkapnya tentang sintaks tersebut, lihat dokumentasi. Untuk tujuan kami, kami dapat mengabaikan {oj dan } closing penutup sebagai kebisingan.

Kesimpulan

Kami melihat bahwa gabungan diperlakukan seolah-olah itu adalah semacam filter dan Access akan mencoba untuk meremote gabungan di tempat yang diizinkan. Satu area khusus yang harus diperhatikan dengan seksama adalah fakta bahwa secara default kita menggunakan recordset tipe dynaset dan Access tidak akan membuat asumsi tentang apakah kita ingin mengizinkan pengubahan kolom ini dan itu dalam recordset dan keluar dari jalan untuk memungkinkan bagi kita untuk memperbarui ke dua tabel yang sebenarnya tidak mudah diekspresikan dalam SQL standar. Akibatnya, Access akan melakukan lebih banyak pekerjaan untuk mendukung pembaruan kueri yang berisi gabungan yang dapat berdampak negatif pada kinerja.

Kami dapat membantu menghindari penalti dengan menggunakan tampilan SQL sebagai pengganti gabungan yang dinyatakan dalam kueri Access. Imbalannya adalah bahwa kita kemudian tunduk pada aturan pembaruan tampilan SQL; kami mungkin tidak diizinkan untuk memperbarui dua tabel secara bersamaan. Biasanya karena formulir Access yang dirancang dengan baik hanya akan mewakili satu tabel untuk diperbarui, itu tidak terlalu membatasi dan merupakan disiplin yang baik untuk diikuti.

Dengan itu, seri saat ini selesai. Namun, pembelajaran yang diharapkan seri ini tidak boleh dilakukan. Saya sangat berharap seri ini bermanfaat bagi Anda dan berharap untuk mendengar tentang wawasan baru yang Anda peroleh dari menggunakan alat untuk membantu menganalisis dan mengatasi masalah kinerja dengan aplikasi Access menggunakan sumber data ODBC. Jangan ragu untuk meninggalkan komentar atau meminta informasi lebih lanjut dan terima kasih telah membaca bersama!

Untuk bantuan lebih lanjut tentang apa pun yang terkait dengan Microsoft Access, hubungi pakar kami di 773-809-5456 atau kirim email kepada kami di [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. Cara Menautkan Tabel ke Database Backend di Access 2016

  2. Fungsi IIf() vs. Pernyataan IIf()

  3. Korupsi Basis Data di MS Access dan Cara Mengatasinya

  4. Temukan Semua Query yang Menggunakan Tabel Tertentu

  5. Akses konektor dataverse sekarang tersedia untuk diuji