Verwaltung und Programmierung


Einführung in die Programmierung für die DB2 Extender

Bevor Sie mit der Entwicklung eines Programms beginnen, das die DB2 Extender verwendet, sollten Sie mit dem DB2-Anwendungsentwicklungsprozeß und den verwendeten Programmiertechniken vertraut sein. Diese werden im Handbuch DB2 Embedded SQL Programming Guide beschrieben. Der Entwicklungsprozeß für Programme, die die DB2 Extender verwenden, ist zum größten Teil identisch mit dem Prozeß für herkömmliche DB2-Anwendungen.

Aufgrund der neuen Datentypen und Funktionen, die von den Extendern definiert werden, unterscheidet sich jedoch der Programmcode der Anwendung von herkömmlichen DB2-Anwendungen. In der folgenden Abbildung wird beispielsweise eine in der Programmiersprache C codierte Anwendung dargestellt, die den Image Extender verwendet, um GIF-Abbilder zu identifizieren, die in einer Datenbanktabelle gespeichert sind. Nach dem Auffinden der Abbilder ruft das Programm einen Abbild-Browser auf, um sie anzuzeigen.

Wie dieses Beispiel verdeutlicht, muß eine Anwendung, die einen DB2 Extender verwendet, folgende Funktionen ausführen:

(1)Extender-Definitionen einschließen. Im angeführten Beispiel ist die Datei dmbimage.h die Include-Datei (Kopfdatei) für den Image Extender. Die Include-Datei definiert die Konstanten, Variablen und Funktionsprototypen für den Extender.

(2)Nach Bedarf Host-Variablen definieren, die Eingaben für oder Ausgaben aus einer benutzerdefinierten Funktion (UDF) oder Eingaben für einen API-Aufruf enthält. Im angeführten Beispiel sind die Variablen hvFormat, hvSize, hvWidth, hvHeight und hvComment Host-Variablen, die verwendet werden, um die Daten aufzunehmen, die von den UDFs des Image Extenders abgerufen wurden. Die Host-Variable hvImg_hdl wird verwendet, um eine Abbildkennung aufzunehmen, das als Eingabe für einen Image Extender-API-Aufruf angegeben wurde.

(3)Nach Bedarf UDF-Anforderungen angeben. Im angeführten Beispiel sind die Funktionen size, width, height, comment und format Image Extender-UDFs.

(4)Nach Bedarf API-Aufrufe definieren. Im angeführten Beispiel ist der Aufruf DBiBrowse ein API-Aufruf einer lokalen Funktion in der Programmiersprache C, die die Abbilder, deren Kennungen aus einer Tabelle abgerufen wurden, anzeigt.

Abbildung 18. Anwendung, die einen DB2 Extender verwendet

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlenv.h>
#include <sqlcodes.h>
#include <dmbimage.h> (1)

int count=0;

long
main(int argc,char *argv[])
{
(2)      EXEC SQL BEGIN DECLARE SECTION;
         char hvImg_hdl[251];                   /* image handle */
         char hvDBName[19];                     /* database name */
         char hvName[40];                       /* employee name */
         char hvFormat[9];                      /* image format */
         long hvSize;                           /* image size */
         long hvWidth;                          /* image width */
         long hvHeight;                         /* image height */
         struct  {
                  short len;
                  char data[32700]
         } hvComment;                           /* comment about the image */
         EXEC SQL END DECLARE SECTION;

/*  Connect to database  */

strcpy(hvDBName, argv[1]);                      /* copy the database name */

EXEC SQL CONNECT TO :hvDBName IN SHARE MODE;
/*
* Set current function path
*/
EXEC SQL SET CURRENT FUNCTION PATH = mmdbsys, CURRENT FUNCTION PATH;

/*
 * Select (query) using Image Extender UDF
 *
 * The SQL statement below finds all images in GIF format.
 */
EXEC SQL DECLARE c1 CURSOR FOR
         SELECT picture, name,                (3)
                size(picture), width(picture),
                height(picture), comment(picture)
         FROM employee
         WHERE picture IS NOT NULL AND
               format(picture) LIKE 'GIF%'
FOR FETCH ONLY;

EXEC SQL OPEN c1;
for (;;) {
         EXEC SQL FETCH c1 INTO :hvImg_hdl, :hvName, :hvSize,
                                :hvWidth, :hvHeight, :hvComment;
         if (SQLCODE != 0)
                   break;

         printf("\nRecord %d:\n", ++count);
         printf("employee name = '%s'\n", hvName);
         printf("image size = %d bytes, width=%d, height=%d\n",
                                                 hvSize, hvWidth, hvHeight);
         hvComment.data[Comment.len]='\0';
         printf("comment len = %d\n", hvComment.len);
         printf("comment = %s\n", hvComment.data);
/*
* The API call below displays the images
*/
(4) rc=DBiBrowse ("ib %s",MMDB_PLAY_HANDLE,hvImg_hdl,
                         MMDB_PLAY_WAIT);
}

EXEC SQL CLOSE c1;

/* end of program */

Extender-Definitionen einschließen

In der Anwendung wird für jeden verwendeten Extender eine Include-Datei (Kopfdatei) benötigt. Jede Include-Datei definiert Konstanten, Variablen und Funktionsprototypen, die vom Extender verwendet werden. Die Include-Dateien haben folgende Namen:

Tabelle 3. Include-Dateien der DB2 Extender
Include-Datei Extender
dmbimage.h Image
dmbqbapi.h Image (Abfrage nach Abbildinhalt)
dmbaudio.h Audio
dmbvideo.h Video
dmbshot.h Video (Ermittlung von Szenenwechseln)

Die Include-Datei wird mit der Anweisung #include in ein C-Programm eingelagert. Die folgende Anweisung lagert beispielsweise die Include-Datei für Image Extender ein:

#include <dmbimage.h>

Namen von benutzerdefinierten Funktionen und Typen angeben

Der vollständige Name einer benutzerdefinierten DB2 Extender-Funktion ist mmdbsys.funktionsname. Der vollständige Name eines benutzerdefinierten DB2 Extender-Typs ist mmdbsys.typname. Hierbei steht mmdbsys für den Schemanamen der Funktion oder des eindeutigen Typs. Der vollständige Name der benutzerdefinierten Funktion "Content" ist beispielsweise mmdbsys.Content; der vollständige Name des vom Image Extender erstellten Datentyps DB2Image ist mmdbsys.DB2Image. Die Angabe des Schemanamens mmdbsys kann übergangen werden, wenn der aktuelle Funktionspfad zuvor wie folgt für mmdbsys definiert wurde:

SET CURRENT FUNCTION PATH = mmdbsys, CURRENT FUNCTION PATH

Große Objekte übertragen

Sie können große Objekte, wie beispielsweise Abbilder, Audioclips und Videoclips, auf verschiedene Weisen zwischen der Anwendung und einer DB2-Datenbank übertragen. Die verwendete Methode hängt davon ab, ob das Objekt aus einer bzw. in eine Datei oder einen Speicherpuffer übertragen wird und ob die Datei sich auf der Client-Maschine oder dem Datenbank-Server befindet.

Objekt zwischen einer Tabelle und einer Server-Datei übertragen

Wenn Sie ein Objekt zwischen einer Datenbanktabelle und einer Server-Datei übertragen, müssen Sie den Dateipfad in der entsprechenden Anforderung für die benutzerdefinierte Extender-Funktion angeben. Da sich die benutzerdefinierte Extender-Funktion und die Datei auf dem Server befinden, kann der Extender die Datei finden. In der folgenden SQL-Anweisung wird beispielsweise ein Abbild, dessen Inhalt sich in einer Server-Datei befindet, in einer Datenbanktabelle gespeichert:

EXEC SQL BEGIN DECLARE SECTION;
  long hvStorageType;
  EXEC SQL END DECLARE SECTION;

hvStorageType=MMDB_STORAGE_TYPE_INTERNAL;

EXEC SQL INSERT INTO employee VALUES(
        '128557',
        'Anita Jones',
        DB2Image(
          CURRENT SERVER,
          '/employee/images/ajones.bmp',
          'ASIS',
          :hvStorageType,
          'Anita''s picture')
       );

Objekt in einen oder aus einem Client-Puffer übertragen

Die Extender können nicht direkt auf einen Speicherpuffer zugreifen. Wenn Sie ein Objekt in einen oder aus einem Puffer auf Ihrer Client-Maschine übertragen wollen, müssen Sie eine Methode verwenden, bei der kein Speicherstandort angegeben wird. Eine Möglichkeit für die Übertragung ist die Verwendung einer Host-Variablen. Mit dieser Methode werden im allgemeinen Objekte zwischen einer Anwendung und einer DB2-Datenbank übertragen.

Host-Variablen für große Objekte werden auf die gleiche Weise definiert und verwendet wie für herkömmliche Zeichenobjekte und numerische Objekte. Sie deklarieren die Host-Variablen in einem DECLARE-Abschnitt, ordnen ihnen Werte für die Übertragung zu oder greifen auf die Werte zu, die an sie übertragen wurden.

Geben Sie den Datentyp BLOB an, wenn Sie eine Host-Variable für Abbild-, Audio- oder Videodaten deklarieren. Wenn Sie eine benutzerdefinierte Funktion (UDF) verwenden, um ein Objekt zu speichern, abzurufen oder zu ändern, wird die entsprechende Host-Variable als Argument in der UDF-Anforderung angegeben. Verwenden Sie das gleiche Format wie für andere Host-Variablen, die in einer SQL-Anweisung angegeben werden.

Im folgenden Beispiel wird durch die SQL-Anweisungen eine Host-Variable mit dem Namen hvaudio deklariert und verwendet, um einen Audioclip an die Datenbank zu übertragen:

EXEC SQL BEGIN DECLARE SECTION;
  SQL TYPE IS BLOB (2M) hvaudio;
  EXEC SQL END DECLARE SECTION;

EXEC SQL INSERT INTO employee VALUES(
        '128557',
        'Anita Jones',
        DB2Audio(
          CURRENT SERVER,
          :hvaudio,
          'WAVE',
          CAST(NULL as LONG VARCHAR),
          'Anita''s voice')
       );

LOB-Zeiger verwenden

Objekte, wie beispielsweise Audio- und Videoclips, können sehr groß sein, so daß die Verwendung von Host-Variablen möglicherweise nicht die effizienteste Methode ist, sie zu bearbeiten. Ein LOB-Zeiger kann eine günstigere Methode sein, LOBs (Large Objects) in Ihren Anwendungen zu bearbeiten.

Ein LOB-Zeiger ist ein kleiner (4 Byte großer) Wert, der in einer Host-Variablen gespeichert ist, und den das Programm verwenden kann, um auf ein wesentlich größeres LOB zu verweisen. Mit Hilfe eines LOB-Zeigers kann das Programm das LOB bearbeiten, als sei es in einer normalen Host-Variablen gespeichert. Der Unterschied liegt darin, daß das LOB nicht zwischen dem Datenbank-Server und der Anwendung auf der Client-Maschine übertragen werden muß. Wenn Sie beispielsweise ein LOB in einer Datenbanktabelle auswählen, verbleibt der LOB auf dem Server und der LOB-Zeiger wird an den Client übertragen.

Ein LOB-Zeiger wird in einem DECLARE-Abschnitt deklariert und auf die gleiche Weise verwendet wie eine Host-Variable. Geben Sie den Datentyp BLOB_LOCATOR an, wenn Sie einen LOB-Zeiger für Abbild-, Audio- oder Videodaten deklarieren. Im folgenden Beispiel wird durch die SQL-Anweisungen ein LOB-Zeiger mit dem Namen video_loc deklariert, um ein ein Videoclip aus einer Datenbanktabelle abzurufen:

EXEC SQL BEGIN DECLARE SECTION;
  SQL TYPE IS BLOB_LOCATOR video_loc;
  EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT content(video)
     INTO :video_loc
     FROM employee
     WHERE name='Anita Jones';

UDFs verwenden LOB-Zeiger: DB2 Extender-UDFs, die Abbild-, Audio- und Videoobjekte speichern, abrufen und aktualisieren, verwenden LOB-Zeiger. Unter DB2 Extender V1 verwendeten diese UDFs keine LOB-Zeiger und konnten aus diesem Grund keine Objekte verarbeiten, die größer als 2 MB waren. Aufgrund dieser Einschränkung waren Benutzer gezwungen, Objekte, die größer als 2 MB waren, in Segmenten zu übertragen. Da diese UDFs jetzt LOB-Zeiger verwenden, entfällt die Einschränkung auf 2 MB.

Objekt in eine oder aus einer Client-Datei übertragen

Eine Dateireferenzvariable wird verwendet, um Objekte in eine oder aus einer Datei auf dem Client zu übertragen. Durch die Verwendung einer Dateireferenzvariablen ist es nicht mehr notwendig, für ein großes Objekt in Ihrem Anwendungsprogramm Pufferbereich zuzuordnen. Wenn Sie eine Dateireferenzvariable mit einer benutzerdefinierten Funktion (UDF) verwenden, findet die Übergabe des BLOB-Inhalts direkt zwischen Datei und UDF statt.

Eine Dateireferenzvariable wird in einem DECLARE-Abschnitt deklariert und auf die gleiche Weise verwendet wie eine Host-Variable. Geben Sie den Datentyp BLOB_FILE an, wenn Sie eine Dateireferenzvariable für Abbild-, Audio- oder Videodaten deklarieren. Im Gegensatz zu einer Host-Variablen, die den Inhalt eines Objekts enthält, enthält eine Dateireferenzvariable den Namen der Datei. Die Datei kann nicht größer sein, als die für die UDF definierte Größe des BLOB.

Für die Verwendung einer Dateireferenzvariablen für die Ein- und Ausgabe bestehen verschiedene Optionen. Wählen Sie die gewünschte Option aus, indem Sie das Feld FILE_OPTIONS in der Struktur der Dateireferenzvariablen im Programm definieren. Folgende Optionen stehen zur Verfügung:

Option für die Eingabe:

SQL_FILE_READ. Diese Datei kann geöffnet, gelesen und geschlossen werden. Die Länge der Daten in der Datei (in Byte) wird beim Öffnen der Datei festgelegt. Das Feld data_length in der Struktur der Dateireferenzvariablen enthält die Länge der Datei (in Byte).

Optionen für die Ausgabe:

SQL_FILE_CREATE. Diese Option erstellt eine neue Datei, falls sie nicht bereits existiert. Existiert die Datei bereits, wird eine Fehlernachricht ausgegeben. Das Feld data_length in der Struktur der Dateireferenzvariablen enthält die Länge der Datei (in Byte).
SQL_FILE_OVERWRITE. Diese Option erstellt eine neue Datei, falls sie nicht bereits existiert. Existiert die Datei bereits, werden die Daten in der Datei durch die neuen Daten überschrieben. Das Feld data_length in der Struktur der Dateireferenzvariablen enthält die Länge der Datei (in Byte).
SQL_FILE_APPEND. Diese Option fügt die Ausgabe an die Datei an, falls die Datei bereits existiert. Existiert die Datei noch nicht, wird eine neue Datei erstellt. Das Feld data_length in der Struktur der Dateireferenzvariablen enthält nicht die Gesamtlänge der Datei, sondern die Länge der zur Datei hinzugefügten Daten (in Byte).

Die Anweisungen im folgenden Beispiel deklarieren eine Dateireferenzvariable mit dem Namen Img_file und verwenden sie, um ein Abbild, dessen Inhalt sich in einer Client-Datei befindet, in einer Datenbanktabelle zu speichern. Beachten Sie die Zuordnung SQL_FILE_READ im Feld FILE_OPTIONS:

EXEC SQL BEGIN DECLARE SECTION;
  SQL TYPE IS BLOB_FILE Img_file;
  EXEC SQL END DECLARE SECTION;

strcpy (Img_file.name,"/employee/images/ajones.bmp");
Img_file.name_length=strlen(Img_file.name);
Img_file.file_options=SQL_FILE_READ;

EXEC SQL INSERT INTO employee VALUES(
        '128557',
        'Anita Jones',
        DB2Image(
          CURRENT SERVER,
          :Img_file,
          'ASIS',
          CAST(NULL as LONG VARCHAR),
          'Anita''s picture')
       );

Dateinamen beim Übertragen von Objekten angeben

Die DB2 Extender geben Ihnen verschiedene Möglichkeiten, wie Sie Dateinamen beim Speichern, Abrufen und Aktualisieren von Objekten angeben können.

Sie können einen vollständig qualifizierten Dateinamen (d. h. einen vollständigen Pfad, gefolgt vom Dateinamen) für Speicher-, Abruf- und Aktualisierungsoperationen angeben; die Angabe eines relativen Pfadnamens ist jedoch vorteilhafter. Unter AIX, HP-UX und Solaris ist ein relativer Dateiname jeder Dateiname, der nicht mit einem Schrägstrich beginnt. Unter OS/2 und Windows ist ein relativer Dateiname jeder Dateiname, der nicht mit einem Laufwerkbuchstaben, gefolgt von einem Doppelpunkt und einem umgekehrte Schrägstrich, beginnt.

Wenn Sie einen relativen Dateinamen angeben, verwenden die Extender die Verzeichnisangaben in den verschiedenen Client- und Server-Umgebungsvariablen, um den Dateinamen aufzulösen. Hierdurch können Dateien in einer Client/Server-Umgebung verschoben werden, ohne daß der Dateiname geändert werden muß. (Ein vollständig qualifizierter Dateiname muß geändert werden, wenn die Datei verschoben wird.) Weitere Informationen zu den Umgebungsvariablen, die von den DB2 Extendern verwendet werden, um Dateinamen aufzulösen, befinden sich in Anhang A. Umgebungsvariablen für DB2 Extender einstellen.

Außerdem setzen die Extender, falls erforderlich, die Formate der Dateinamen um. Wird ein Dateiname an den Server übergeben, wird er in das Dateiformat für das Betriebssystem des Servers umgesetzt. So wird z. B. ein OS/2-Dateiname, wie etwa :\dir1\abc.bmp in das Format /dir1/abc.bmp umgesetzt, wenn er an einen AIX-Server übergeben wird.

Rückkehrcodes verwenden

Alle eingebetteten SQL-Anweisungen oder DB2 CLI-Aufrufe in Ihrem Programm, einschließlich derer, die DB2 Extender UDFs aufrufen, generieren Codes, die angeben, ob die eingebettete SQL-Anweisung oder der DB2 CLI-Aufruf erfolgreich ausgeführt wurde. Andere DB2 Extender-APIs, wie z. B. Verwaltungs-APIs, geben auch Code zurück, der angibt, ob die API erfolgreich oder nicht erfolgreich ausgeführt wurde. Ihr Programm sollte die Codes, die von eingebetteten SQL-Anweisungen, CLI-Aufrufen und APIs zurückgegeben werden, überprüfen und entsprechend auf sie reagieren.

Informationen zur Verwendung dieser Rückkehrcodes befinden sich in Kapitel 19. Diagnoseinformationen.


[ Seitenanfang | Vorherige Seite | Nächste Seite | Inhaltsverzeichnis | Index ]

Search the DB2 Extender Books