Alignment

ODBC 應用程式的對齊問題通常與其他應用程式沒什麼不同。 也就是說,大部分的 ODBC 應用程式在對齊方面都不太會有問題。 不對齊位址的後果因硬體與作業系統而有所不同,可能小至輕微的效能損失,也可能大到嚴重的執行階段錯誤。 因此,對於 ODBC 應用程式,特別是可攜式 ODBC 應用程式,應該特別留意資料的對齊。

舉例來說,當 ODBC 應用程式配置了大型的記憶體區塊,並將該記憶體的不同部分繫結至結果集的資料行時,便可能發生對齊問題。 當泛型應用程式必須在執行階段判斷結果集的圖形,據以配置並繫結記憶體時,就很可能會發生這種情況。

例如,假設應用程式執行使用者輸入的 SELECT 陳述式,並從這個陳述式擷取結果。 由於撰寫程式時不會知道此結果集的圖形,應用程式必須在建立結果集後確認每個資料行的類型,並據此繫結記憶體。 最簡單的方式是配置一個大型的記憶體區塊,並將該區塊的不同位址繫結至每個資料行。 為了存取某一行資料行的資料,應用程式會記憶體繫結轉換至該資料行。

下圖是一個結果集範例,並顯示如何使用每個 SQL 資料類型的預設 C 資料類型將記憶體區塊繫結至此結果集。 每個 "X" 都代表單一個位元組的記憶體。 (本範例只顯示了繫結至資料行的資料緩衝區。這是為了便於說明。在實際程式碼中,長度/指標緩衝區也必須對齊。)

Binding by default C data type to SQL data type

假設繫結位址儲存在「位址」陣列,應用程式會使用下列運算式來存取繫結至每個資料行的記憶體:

(SQLCHAR *)       Address[0]  
(SQLSMALLINT *)   Address[1]  
(SQLINTEGER *)    Address[2]  

請注意,繫結至第二與第三個資料行的位址會以奇數編號位元組開始,而繫結至第三個資料行的位址不能被 4 整除 (4 為一個 SDWORD 的大小)。 在有些機器上,這不會是問題;在有些機器,這會導致效能稍微降低;但在某些機器上,則可能會導致嚴重的執行階段錯誤。 更好的解決方案是將每個繫結位址對齊在其自然的對齊界限上。 假設這是 UCHAR 為 1,一個 SWORD 為 2,另一個 SDWORD 為 4,這會得出下圖所示的結果,其中 "X" 代表使用的位元組記憶體,而 "O" 則代表未使用的記憶體位元組。

Binding by natural alignment boundary

儘管此解決方案不會使用所有應用程式的記憶體,但不會發生任何的對齊問題。 不幸的是,實作此解決方案需要撰寫大量的程式碼,因為每個資料行都必須根據其類型個別對齊。 一個更為簡單的解決方案是,根據最大對齊界限的大小來對齊所有資料行,在下圖所示範例中為 4。

Binding by largest alignment boundary

儘管此解決方案會留下較大漏洞,但實作此程式碼相對簡單快速。 在大部分情況下,這能抵銷記憶體未使用所帶來的損失。 如需使用此方法的範例,請參閱使用 SQLBindCol