PostgreSQL Datenbankpraxis für Anwender, Administratoren und Entwickler

Kapitel 9 - Clientseitige Programmierung

Seite 276

Notwendige Bibliotheken einbinden

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"


Verbindung mit PQconnectdb()

PGconn *conninfo;
conninfo = PQconnectdb( (const char *) "connect string");


Connect String

host=localhost port=5434 user=admin
password=ganzgeheim dbname='verwaltung'

Seite 277

Fehlerbehandlung in C

if (PQstatus(conninfo) == CONNECTION_BAD) {
  /* Fehlerbehandlung */
} else if (PQstatus(conninfo) == CONNECTION_OK) {
  /* alles in Ordnung */
} else {
  /* sollte nicht auftreten */
}


Die veraltete Funktion PGsetdbLogin()

PGconn *conninfo;
conninfo = PQsetdbLogin(const char *pghostname,
                        const char *pgport,
                        const char *pgoptionen,
                        const char *pgtty,
                        const char *datenbankname,
                        const char *benutzername,
                        const char *passwort);


Asynchrone Anfrage starten

PGconn *PQconnectStart( (const char *) "connect string");
PostgresPollingStatusType PQconnectPoll(PGconn *conn);

Seite 278

Speicher freigeben

void PQfreemem(void *zeiger);


Verbindung schließen

void PQfinish(PGconn *conn);

Seite 279

Verbindung zurücksetzen

void PQreset(PGconn *conn);

void PQresetStart(PGconn *conn);
PostgresPollingStatusType PQresetPoll(PGconn *conn);


Eine Anfrage stellen

PGresult *result;
result = *PQexec(PGconn *conninfo, const char *befehl);

Seite 280

Ergebnis freigeben

PQclear(result);


Parameter für die Anfrage gesondert angeben

PGresult *result;
result = *PQexecParams(PGconn *conninfo,
                       const char *befehl,
                       int AnzahlParameter,
                       const Oid *ParameterTypen,
                       const char *ParameterWerte,
                       const int *ParameterLaenge,
                       const int *ParameterFormat,
                       int ErgebnisFormat);

Seite 281

Eine Anfrage vorbereiten

PGresult *result;
result = *PQprepare(PGconn *conninfo,
                    const char *statementName,
                    const char *befehl,
                    int anzahlParameter,
                    const Oid *parameterTypen);

Seite 282

Eine vorbereitete Anfrage ausführen

PGresult *result;
result = *PQexecPrepared(PGconn *conninfo,
                         const char *statementName,
                         int anzahlParameter,
                         const char *parameterWerte,
                         const int *paramLengths,
                         const int *paramFormats,
                         int resultFormat);


Ergebnis der Anfrage feststellen

PGresult *result;
result = *PQexec(PGconn *conninfo, "SELECT ...");
if (PQresultStatus(result) != PGRES_TUPLES_OK) {
  fprintf(stderr, "Fehler: %s", PQerrorMessage(conninfo));
  fprintf(stderr, "Fehler: %s", PQresultErrorMessage(result));
}

Seite 283

Verbindungsstatus ermitteln

fprintf(stderr, "Text: %s", *PQresStatus(PGRES_TUPLES_OK);


Fehlermeldungen ausgeben

fprintf(stderr, "Fehler: %s", PQerrorMessage(conninfo));
fprintf(stderr, "Fehler: %s", PQresultErrorMessage(result));

Seite 284

Einen String quoten

size_t laenge_gequoted;
laenge_gequoted = PQescapeStringConn(
                    PGconn *conninfo,
                    char *gequoted,
                    char *original,
                    size_t laenge_original,
                    int *fehler);

Seite 285

Binärdaten quoten

char *gequoted;
size_t laenge_gequoted;
gequoted = PQescapeByteaConn(
             PGconn *conn,
             const unsigned char *original,
             size_t laenge_original,
             size_t *laenge_gequoted);


Binäre gequotete Daten zurückwandeln

char *n_gequoted;
size_t laenge_n_gequoted;
n_gequoted = PQunescapeBytea(
               const unsigned char *gequoted,
               size_t *laenge_n_gequoted);

Seite 286

Spaltennummer

  int spaltenNummer;
  spaltenNummer = PQfnumber(result, "spaltenname");


Ergebnisanzahl ermitteln

  int anzahlErgebnisse;
  anzahlErgebnisse = PQntuples(result);


Alle Ergebnisse ausgeben

  int pos;
  for (pos = 0; pos < PQntuples(result); pos++) {
    ...
  }


NULL-Werte ermitteln

  int ist_null;
  ist_null = PQgetisnull(result, 5, PQfnumber(result, "ergebnis"));


Einen bestimmten Datensatz auslesen

  char *ergebnis;
  ergebnis = PQgetvalue(result, 5, PQfnumber(result, "ergebnis"));

Seite 287

Länge eines Datensatzes feststellen

  int textLaenge;
  textLaenge = PQgetlength(result, 5, PQfnumber(result, "ergebnis"));


Daten ausgeben

  int pos;
  for (pos = 0; pos < textLaenge; pos++) {
    printf("%03o", ergebnis[pos]);
  }

Seite 288

Include-Dateien

  #include <iostream>
  #include <pqxx/pqxx>
  #include <pqxx/result>
  #include <pqxx/execpt>

  using namespace std;
  using namespace pqxx;


Verbindung öffnen

  try {
    connection Verbindung1("connect string");
  }


Verbindung schließen

  Verbindung1.disconnect();

Seite 289

Fehler abfangen

  try {
    ... fehlerhafte Anweisung
  }
  catch (const sql_error &e) {
    // es ist ein SQL Fehler aufgetreten, den Benutzer informieren:
    cerr << "SQL Fehler: " << e.what() << endl;
    cerr << "Anfrage: " << e.query() << endl;
  }
  catch (const exception &e) {
    // es ist ein anderer Fehler aufgetreten
    cerr << "Fehler: " << e.what() << endl;
  }


Transaktion starten

  work Transaktion1(Verbindung1);


Eigener Bezeichner

  work Transaktion1(Verbindung1, "Beispielverbindung");
  transaction<> Transaktion1(Verbindung1, "Beispielverbindung");


Abschließen

  Transaktion1.commit();

Seite 290

Abbrechen

  Transaktion1.abort();


Anfrage ohne Ergebnis

  Transaktion1.exec("UPDATE tabelle SET ...");


Anfrage mit Ergebnis

  result Resultate;
  Resultate = Transaktion1.exec("SELECT id, wert FROM tabelle");
  cout << "Habe " << Resultate.size() << " Einträge." << endl;
  for (result::const_iterator r = Resultate.begin();
       r != Resultate.end(); ++r) {
    cout << r[0].c_str() << ": " r[1].c_str() << endl;
  }

Seite 291

Notwendige Bibliotheken laden

using System;
using System.Data;
using Npgsql;

NpgsqlConnection connection;


Verbindung zur Datenbank herstellen

try {

  string str_connect_string  = "Server=localhost";
         str_connect_string += ";User=ads";
         str_connect_string += ";Database=pg_buch";

  connection = new NpgsqlConnection(str_connect_string);
  connection.Open();
}
catch (Exception e) {
    ... Fehlerbehandlung
}

Seite 293

Verbindung schließen

  connection.Close();
  // zusätzlich die Ressourcen wieder freigeben:
  connection = null;


Anweisung ohne Ergebnis ausführen

  string anweisung  = "INSERT INTO tabelle";
         anweisung += " (...) VALUES (...)";

  NpgsqlCommand befehl = new NpgsqlCommand(anweisung, connection);
  int geaenderte_zeilen;

  try {
      geaenderte_zeilen = befehl.ExecuteNonQuery();
      Console.WriteLine("{0} Zeilen eingefügt", geaenderte_zeilen);
  }
  catch (Exception e) {
      ... Fehlerbehandlung
  }

Seite 294

Anweisung mit einem Ergebnis

  string anweisung  = "SELECT COUNT(*) AS count";
         anweisung += " FROM tabelle";

  NpgsqlCommand befehl =
      new NpgsqlCommand(anweisung, connection);
  int anzahl;

  try {
      anzahl = Convert.ToInt32(befehl.ExecuteScalar());
      Console.WriteLine("{0} Zeilen in Tabelle", anzahl);
  }
  catch (Exception e) {
      ... Fehlerbehandlung
  }


Anweisung mit beliebigen Ergebnissen

  string anweisung = "SELECT id, wert FROM tabelle";

  NpgsqlCommand befehl =
      new NpgsqlCommand(anweisung, connection);

  try {
      NpgsqlDataReader dr = befehl.ExecuteReader();
      Console.Write("id: wert");
      Console.WriteLine();
      while (dr.Read()) {
          Console.WriteLine("{0}: {1}",
              Convert.ToInt32(dr["id"]),
              Convert.ToString(dr["wert"]));
          Console.WriteLine();
      }
  }
  catch (Exception e) {
    ... Fehlerbehandlung
  }

Seite 295

Cursor definieren

  // Cursor definieren
  string anweisung  = "DECLARE daten CURSOR FOR ";
         anweisung += "SELECT id, wert FROM tabelle";

  NpgsqlTransaction transaktion = connection.BeginTransaction();
  NpgsqlCommand befehl = new NpgsqlCommand(anweisung, connection);

  // Cursor erzeugen
  try {
    befehl.ExecuteNonQuery();
  }
  catch (Exception e) {
    ... Fehlerbehandlung
    transaktion.Rollback();
  }

  // den Cursor auf den nächsten 5 Datensätzen positionieren
  befehl.CommandText = "FETCH FORWARD 5 FROM daten";

  try {
      NpgsqlDataReader dr = befehl.ExecuteReader();
      Console.Write("id: wert");
      Console.WriteLine();
      while (dr.Read()) {
          Console.WriteLine("{0}: {1}",
              Convert.ToInt32(dr["id"]),
              Convert.ToString(dr["wert"]));
          Console.WriteLine();
      }
  }
  catch (Exception e) {
      ... Fehlerbehandlung
      transaktion.Rollback();
  }

  // Cursor wieder schließen
  anweisung = "CLOSE daten";

  befehl = new NpgsqlCommand(anweisung, connection);

  try {
      befehl.ExecuteNonQuery();
  }
  catch (Exception e) {
      ... Fehlerbehandlung
      transaktion.Rollback();
  }

  transaktion.Commit();

Seite 296

Parameter getrennt übergeben

  string anweisung  = "SELECT id, wert FROM tabelle";
         anweisung += " WHERE id = :value1";

  // Anweisung vorbereiten
  NpgsqlCommand befehl =
      new NpgsqlCommand(anweisung, connection);

  // Name und Typ des Parameters zuweisen
  befehl.Parameters.Add(
      new NpgsqlParameter("value1", DbType.Int32));

  // Wert zuweisen
  befehl.Parameters[0].Value = 23;

  // ab hier Befehl normal ausführen


Binäre Daten

  // Name und Typ des Parameters zuweisen
  befehl.Parameters.Add(new NpgsqlParameter("bild1", DbType.Binary));

Seite 297

Transaktion starten

  NpgsqlTransaction transaktion = connection.BeginTransaction();


Abschließen

  transaktion.Commit();


Abbrechen

  transaktion.Rollback();


Transaktionslevel festlegen

  NpgsqlTransaction transaktion =
      connection.BeginTransaction(IsolationLevel.ReadCommitted);


Fehler abfangen, Benutzer informieren

  // diese Anweisung enthält einen Syntax-Fehler:
  string anweisung  = "INSERT FROM tabelle";
         anweisung += " (...) VALUES (...)";

  NpgsqlCommand befehl = new NpgsqlCommand(anweisung, connection);
  int geaenderte_zeilen;

  try {
      geaenderte_zeilen = Convert.ToInt32(befehl.ExecuteNonQuery());
      Console.WriteLine("{0} Zeilen eingefügt", geaenderte_zeilen);
  }
  catch (Exception e) {
      // den unweigerlich auftretenden Fehler ausgeben:
      Console.WriteLine("Fehler: " + e.Message);
  }

Seite 298

Detaillierte Fehlermeldungen

  catch (NpgsqlException ex) {
      Console.WriteLine("Fehlercode: " + ex.Code);
      Console.WriteLine("Fehlermeldung: " + ex.Message);
      Console.WriteLine("Fehlermeldung detailliert: " + ex.Detail);
      Console.WriteLine("Hinweis: " + ex.Hint);
  }


Logdatei schreiben

  NpgsqlEventLog.Level = LogLevel.Normal;
  NpgsqlEventLog.LogName = "/tmp/anwendung.log";
  NpgsqlEventLog.EchoMessages = true;

Seite 299

Debian GNU/Linux

apt-get install libdbd-pg-perl


Red Hat Linux

yum install perl-DBD-Pg


DBI aus CPAN

cpan DBI


DBI laden

use DBI;

Seite 300

Verbindung aufbauen

my $db = DBI->connect("dbi:Pg:dbname=$name;host=$host",
                      $benutzername, $passwort,
                      {AutoCommit => 0});

Seite 301

Optionen in pg_service.conf

[servicename]
parameter=value
parameter=value
...

Seite 302

Autocommit aus

$db->{AutoCommit} = 0;


Schließen

$db->disconnect;

Seite 303

Fehlercode

print $db->err . "\n";


Fehlermeldung

print $db->errstr . "\n";


Fehlercode

print $db->err . "\n";
print $DBI::err . "\n";


Fehlermeldung

print $db->errstr . "\n";
print $DBI::errstr . "\n";

Seite 304

Befehl an die Datenbank senden

my $query = "UPDATE tabelle SET daten = 'neu'";
if (!$db->do($query)) {
  # Fehlerbehandlung
}


Befehl vorbereiten und senden

my $query = "SELECT daten FROM tabelle";
my $st = $db->prepare($query);
if (!$st->execute) {
  # Fehlerbehandlung
}


Befehl vorbereiten und wiederholt senden

my $query = "SELECT daten FROM tabelle WHERE id = ?";
my $st = $db->prepare($query);

my $id = 23;
if (!$st->execute($id)) {
  # Fehlerbehandlung
}
...
$id = 42;
if (!$st->execute($id)) {
  # Fehlerbehandlung
}

Seite 305

quote nutzen zum Escapen von Parametern

my $query = "SELECT daten
               FROM tabelle
              WHERE id = " . $db->quote($id) . "";
my $st = $db->prepare($query);

if (!$st->execute) {
  # Fehlerbehandlung
}

Seite 306

Daten abrufen

while (my @zeile = $st->fetchrow_array) {
  print "Spalte 1: " . $zeile[0] . "\n";
  print "Spalte 2: " . $zeile[1] . "\n";
}

while (my $zeile = $st->fetchrow_arrayref) {
  print "Spalte 1: " . $zeile->[0] . "\n";
  print "Spalte 2: " . $zeile->[1] . "\n";
}

while (my $zeile = $st->fetchrow_hashref) {
  print "Spalte id: " . $zeile->{'id'} . "\n";
  print "Spalte wert: " . $zeile->{'wert'} . "\n";
}


Daten abrufen

my $zeilen = $st->fetchall_arrayref;
for my $zeile (@$zeilen) {
  print "Spalte 1: " . $zeile->[0] . "\n";
  print "Spalte 2: " . $zeile->[1] . "\n";
  my @zeile = @$zeile;
  print "Spalte 1: " . $zeile[0] . "\n";
  print "Spalte 2: " . $zeile[1] . "\n";
}

my $zeilen = $st->fetchall_hashref('id');
print "Spalte id, Zeile 42: " . $zeilen->{42}->{'id'} . "\n";
print "Spalte wert, Zeile 42: " . $zeilen->{42}->{'wert'} . "\n";

Seite 307

Daten abrufen

$db->{RaiseError} = 1;
my @erg = $db->selectrow_array("SELECT COUNT(*)
                                  FROM nachrichten");
print "Anzahl Nachrichten: " . @erg[0] . "\n";

Seite 308

Daten abrufen

$db->{RaiseError} = 1;
my $erg = $db->selectall_arrayref("SELECT nachname
                                     FROM adressbuch
                                 ORDER BY nachname");

if (!$erg) {
  # ein Fehler ist aufgetreten ...
}
foreach my $name (@$erg) {
  print "Name: " . $name->{nachname} . "\n";
}


Daten abrufen

$db->{RaiseError} = 1;
my $erg = $db->selectrow_array("SELECT id, wert
                                  FROM daten",
                               {Columns=>[1,2]});

if (!$erg) {
  # ein Fehler ist aufgetreten ...
}
my %ergebnis = @$erg


Anzahl der Ergebnisse

$anzahl = $st->rows();
print "Anzahl Ergebnisse: $anzahl\n";

Seite 309

Ergebnis freigeben

$st->finish;


AutoCommit ein- und ausschalten

$db->{AutoCommit} = 0; # Aus
$db->{AutoCommit} = 1; # Ein


Transaktion abschließen

$db->commit;


Zurückrollen

$db->rollback;


Neue Transaktion

$db->begin_work;

Seite 310

Unix

extension=pgsql.so


Windows

extension=pgsql.dll

Seite 311

Verbindungsaufbau

$db = pg_connect("connect string");
if (!$db) {
  ... Fehlerbehandlung
}

Seite 312

Persistente Verbindung

$db = pg_pconnect("connect string");
if (!$db) {
  ... Fehlerbehandlung
}


Verbindung wieder schließen

$ergebnis = pg_close($db);

Seite 313

Fehler erzeugen und abfangen

# die folgende Anfrage wird einen Fehler produzieren,
# da sie syntaktisch falsch ist
$anfrage = "SELECT";
$ergebnis = pg_query($db, $anfrage);
if ($ergebnis === false) {
  # Fehlerbehandlung
  print pg_last_error($db) . "\n";
}
# Achtung: Fehler...


Letzter Hinweis

print pg_last_notice($db) . "\n";

Seite 314

Anfragen stellen

$anfrage = "SELECT id, vorname, nachname
              FROM adressen
             WHERE nachname='" . pg_escape_string($name) . "'";
if (!pg_query($db, $anfrage)) {
  # es gab einen Fehler, dieser muss hier behandelt werden
}


Anfrage vorbereiten

$ergebnis = pg_prepare($db, $statementname, $anfrage);


Anfrage vorbereiten

$anfrage = "SELECT id, vorname, nachname
              FROM adressen
             WHERE nachname = $1";
$statementname = "Adresse";
$ergebnis = pg_prepare($db, $statementname, $anfrage);

Seite 315

Ausführen

$statementname = "Adresse";
$ergebnis = pg_execute($db, $statementname, array("O'hare"));

Seite 316

while-Schleife

while ($zeile = pg_fetch_row($ergebnis)) {
  print "Spalte 1: " . $zeile[0] . "\n";
  print "Spalte 2: " . $zeile[1] . "\n";
}
while ($zeile = pg_fetch_assoc($ergebnis)) {
  print "Spalte id: " . $zeile['id'] . "\n";
  print "Spalte wert: " . $zeile['wert'] . "\n";
}


foreach-Schleife

$array = pg_fetch_all($ergebnis);
foreach ($array as $schluessel => $wert) {
  print "Zeile: " . ($schluessel + 1) . "\n";
  print "Wert 1: " . $wert['spalte1'] . "\n";
  print "Wert 2: " . $wert['spalte2'] . "\n";
}


Anzahl der Ergebnisse

$anzahl = pg_num_rows($ergebnis);
print "Anzahl Ergebnisse: $anzahl\n";


Anzahl der Spalten

$zeile = pg_num_fields($ergebnis);
print "Anzahl Spalten: $anzahl\n";

Seite 317

Anzahl geänderter Werte herausfinden

$anfrage = "DELETE FROM tabelle";
$ergebnis = pg_query($db, $anfrage);
if (!$ergebnis) {
  # Fehlerbehandlung
}
$anzahl = pg_affected_rows($ergebnis);
print "Anzahl geänderter Zeilen: $anzahl\n";


Ergebnis freigeben

pg_free_result($ergebnis);


Starten

$ergebnis = pg_query($db, "START TRANSACTION");

Seite 318

Zurückrollen

$ergebnis = pg_query($db, "ROLLBACK");


Abschließen

$ergebnis = pg_query($db, "COMMIT");

Verbindungsaufbau

include_once("/pfad/zu/adodb.inc.php");

==== Seite 319 ====

$db = NewADOConnection('postgres');
$ergebnis = $db->Connect("hostname",
                         "benutzername",
                         "passwort",
                         "datenbankname");
if (!$ergebnis) {
  # Verbindung konnte nicht hergestellt werden
  # hier Fehlerbehandung einfügen
}


Verbindungsdaten als String angeben

$db = NewADOConnection('postgres');
$ergebnis = $db->Connect("connect string");
if (!$ergebnis) {
  ... Fehlerbehandlung
}


Data Source Name

treiber://benutzername:passwort@hostname/datenbank?option[=wert]


Verbindungsaufbau mit DSN

$dsn = "postgres://benutzername:passwort@hostname/datenbank";
$db = NewADOConnection($dsn);
if (!$db) {
  ... Fehlerbehandlung
}

Seite 320

Persistente Verbindung

include_once("/pfad/zu/adodb.inc.php");

$db = NewADOConnection('postgres');
$ergebnis = $db->PConnect(...);


Neue Verbindung

$ergebnis = $db->NConnect(...);


Verbindung schließen

$db->Close();


Daten abfragen

$anfrage = "SELECT id, vorname, nachname
              FROM adressen
             WHERE nachname='" . pg_escape_string($name) . "'";
$ergebnis = $db->Execute($anfrage);
if (!$ergebnis) {
  # Fehlerbehandlung
}

Seite 321

Anfragen cachen

$ADODB_CACHE_DIR = '/pfad/zum/ADOdbcache';
$ergebnis = $db->CacheExecute([Cache Zeit], $anfrage);


Cache-Zeitdauer

$db->cacheSecs = 600; # in Sekunden


Ergebnis auslesen

while (!$ergebnis->EOF) {
  print "Spalte 1: " . $ergebnis->fields[0] . "\n"; # ID
  print "Spalte 2: " . $ergebnis->fields['vorname'] . "\n";
  print "Spalte 3: " . $ergebnis->fields['nachname'] . "\n";
  $ergebnis->MoveNext(); # zur nächsten Zeile springen
}


Fetchmode festlegen

$db->SetFetchMode(ADODB_FETCH_DEFAULT);
$db->SetFetchMode(ADODB_FETCH_NUM);
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$db->SetFetchMode(ADODB_FETCH_BOTH);

Seite 322

Anzahl Ergebnisse

$anzahl = $ergebnis->RecordCount();


Name und Typ der Ergebnisspalten herausfinden

$spalten = $ergebnis->FieldCount();
for ($i = 0; $i < $spalten; $i++) {
  $spalte = $ergebnis->FetchField($i);
  print "Name: " . $spalte->name . "\n";
  print " Typ: " . $spalte->type . "\n";
}

Seite 323

Geänderte Spalten

$anzahl = $db->Affected_Rows();


LIMIT

$ergebnis = $db->SelectLimit($query, 5);


OFFSET

$ergebnis = $db->SelectLimit($query, 10, 20);


Ergebnis freigeben

$ergebnis->Close(); # Ressourcen freigeben

Seite 324

Fehlermeldung

print $conn->ErrorMsg() . "\n";


Exceptions ermöglichen

include_once("/pfad/zu/adodb-exceptions.inc.php");
include_once("/pfad/zu/adodb.inc.php");

try {
  $db = NewADOConnection($dsn);
} catch (exception $exception) {
  var_dump($exception);
  adodb_backtrace($exception->gettrace());
}


Exceptions ermöglichen

include_once("/pfad/zu/adodb-errorhandler.inc.php");
include_once("/pfad/zu/adodb.inc.php");
include_once("/pfad/zu/tohtml.inc.php");

# Ausgaben auch wirklich anzeigen
ini_set("display_errors", "1");

# Alle Meldungen (auch Notizen) ausgeben
error_reporting(E_ALL);

# oder: Meldungen ausgeben, aber Notizen ignorieren
error_reporting(E_ALL & ~E_NOTICE);


Exceptions ermöglichen

include_once("/pfad/zu/adodb-errorpear.inc.php");
include_once("/pfad/zu/adodb.inc.php");
include_once("/pfad/zu/tohtml.inc.php");

...
$ergebnis = NewADOConnection($dsn);
if (!$ergebnis) {
  $exception = ADODB_Pear_Error();
  print "Fehler:" . $exception->message . "\n";
}

Seite 325

Verbindungsaufbau

EXEC SQL CONNECT TO ziel [AS verbindungsname] [USER benutzername];

Seite 326

Verbindungsaufbau

EXEC SQL BEGIN DECLARE SECTION;
const char *ziel = "testdb@sql.meinedomain.de";
const char *benutzername = "klaus";
EXEC SQL END DECLARE SECTION;
 ...
EXEC SQL CONNECT TO :ziel USER :benutzername;


Implizit deklarieren

EXEC SQL long variable = 4;


Schließen

EXEC SQL DISCONNECT [verbindungsname];

Seite 327

Kompilieren

ecpg beispiel.pgc
cc -lecpg -o beispiel beispiel.c

Seite 328

Anfragen stellen

EXEC SQL SELECT spalte1 FROM tabelle;
EXEC SQL INSERT INTO tabelle (spalte1) VALUES (:variable);


Anfragen stellen und Daten abrufen

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR variable;
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT spalte1 INTO :variable FROM tabelle;


Anfragen stellen und Daten abrufen

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR variable;
EXEC SQL END DECLARE SECTION;

EXEC SQL DECLARE fetch_cursor CURSOR FOR SELECT spalte1 FROM tabelle;

do {
    EXEC SQL FETCH NEXT FROM fetch_cursor INTO :variable;
} while (...);


NULL-Werte erkennen

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR variable;
int null_indikator;
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT spalte1 INTO :variable :null_indikator FROM tabelle;

Seite 329

Anfrage dynamisch zusammenstellen

EXEC SQL BEGIN DECLARE SECTION;
const char *anfrage = "INSERT INTO tabelle (spalte1) VALUES($1);";
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE prep_anfrage FROM :anfrage;
EXEC SQL EXECUTE prep_anfrage USING 23;
EXEC SQL DEALLOCATE PREPARE prep_anfrage;


Daten mit dynamisch ersteller Anfrage auslesen

EXEC SQL BEGIN DECLARE SECTION;
const char *anfrage = "SELECT spalte1 FROM tabelle WHERE id = $1;";
VARCHAR variable;
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE prep_anfrage FROM :anfrage;
EXEC SQL EXECUTE prep_anfrage INTO variable USING 23;