Freigeben über


Ausrichtung

Die Ausrichtungsprobleme in einer ODBC-Anwendung unterscheiden sich in der Regel nicht von denen in einer anderen Anwendung. Das heißt, die meisten ODBC-Anwendungen haben nur wenige oder keine Probleme mit der Ausrichtung. Die Bestrafungen für die fehlende Ausrichtung von Adressen variieren je nach Hardware und Betriebssystem und können von geringfügigen Leistungseinbußen bis hin zu schwerwiegenden Laufzeitfehlern reichen. Daher sollten ODBC-Anwendungen und portable ODBC-Anwendungen insbesondere darauf achten, Daten ordnungsgemäß auszurichten.

Ein Beispiel dafür, dass BEI ODBC-Anwendungen Ausrichtungsprobleme auftreten, besteht darin, dass sie einen großen Speicherblock zuweisen und unterschiedliche Teile dieses Speichers an die Spalten in einem Resultset binden. Dies tritt höchstwahrscheinlich auf, wenn eine generische Anwendung das Shape eines Resultsets zur Laufzeit bestimmen und Speicher entsprechend zuordnen und binden muss.

Angenommen, eine Anwendung führt eine SELECT-Anweisung aus, die vom Benutzer eingegeben wurde, und ruft die Ergebnisse aus dieser Anweisung ab. Da die Form dieses Resultsets beim Schreiben des Programms nicht bekannt ist, muss die Anwendung den Typ jeder Spalte bestimmen, nachdem das Resultset erstellt wurde, und speicher entsprechend binden. Am einfachsten können Sie dies tun, um einen großen Speicherblock zuzuweisen und verschiedene Adressen in diesem Block an jede Spalte zu binden. Um auf die Daten in einer Spalte zuzugreifen, führt die Anwendung ein Casting des an diese Spalte gebundenen Speichers durch.

Das folgende Diagramm zeigt ein Beispiel-Resultset und wie ein Speicherblock mit dem standardmäßigen C-Datentyp für jeden SQL-Datentyp an ihn gebunden werden kann. Jedes "X" stellt ein einzelnes Byte des Arbeitsspeichers dar. (Dieses Beispiel zeigt nur die Datenpuffer, die an die Spalten gebunden sind. Dies geschieht aus Gründen der Einfachheit. Im tatsächlichen Code müssen auch die Längen-/Indikatorpuffer ausgerichtet werden.)

Standardmäßige Zuordnung des C-Datentyps zum SQL-Datentyp

Vorausgesetzt, die gebundenen Adressen werden im Adressarray gespeichert, verwendet die Anwendung die folgenden Ausdrücke, um auf den an jede Spalte gebundenen Speicher zuzugreifen:

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

Beachten Sie, dass die adressen, die an die zweite und dritte Spalte gebunden sind, bei ungeraden Bytes beginnen und dass die an die dritte Spalte gebundene Adresse nicht durch vier divisierbar ist, was die Größe eines SDWORD ist. Auf einigen Computern ist dies kein Problem; bei anderen wird dies zu einer leichten Leistungsstrafe führen; bei noch anderen verursacht dies einen schwerwiegenden Laufzeitfehler. Eine bessere Lösung wäre, jede gebundene Adresse an ihrer natürlichen Ausrichtungsgrenze auszurichten. Angenommen, dies ist 1 für eine UCHAR, 2 für ein SWORD und 4 für ein SDWORD, würde dies das in der folgenden Abbildung gezeigte Ergebnis liefern, wobei ein "X" ein Byte des verwendeten Speichers darstellt und ein "O" ein Byte des ungenutzten Speichers.

Bindung durch natürliche Ausrichtungsgrenze

Obwohl diese Lösung nicht den gesamten Arbeitsspeicher der Anwendung verwendet, tritt keine Ausrichtungsprobleme auf. Leider erfordert es einen beträchtlichen Code, um diese Lösung umzusetzen, denn jede Spalte muss einzeln nach ihrem Typ ausgerichtet werden. Eine einfachere Lösung besteht darin, alle Spalten an der Größe der größten Ausrichtungsgrenze auszurichten, die 4 im Beispiel in der folgenden Abbildung dargestellt ist.

Bindung an die größte Ausrichtungsgrenze

Obwohl diese Lösung größere Löcher hinterlässt, ist der Code zur Implementierung relativ einfach und schnell. In den meisten Fällen wird dadurch die Strafe ausgeglichen, die im nicht genutzten Speicher bezahlt wird. Ein Beispiel, das diese Methode verwendet, finden Sie unter Verwenden von SQLBindCol.