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'
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);
Speicher freigeben
void PQfreemem(void *zeiger);
Verbindung schließen
void PQfinish(PGconn *conn);
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);
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);
Eine Anfrage vorbereiten
PGresult *result; result = *PQprepare(PGconn *conninfo, const char *statementName, const char *befehl, int anzahlParameter, const Oid *parameterTypen);
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)); }
Verbindungsstatus ermitteln
fprintf(stderr, "Text: %s", *PQresStatus(PGRES_TUPLES_OK);
Fehlermeldungen ausgeben
fprintf(stderr, "Fehler: %s", PQerrorMessage(conninfo)); fprintf(stderr, "Fehler: %s", PQresultErrorMessage(result));
Einen String quoten
size_t laenge_gequoted; laenge_gequoted = PQescapeStringConn( PGconn *conninfo, char *gequoted, char *original, size_t laenge_original, int *fehler);
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);
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"));
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]); }
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();
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();
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; }
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 }
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 }
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 }
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();
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));
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); }
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;
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;
Verbindung aufbauen
my $db = DBI->connect("dbi:Pg:dbname=$name;host=$host", $benutzername, $passwort, {AutoCommit => 0});
Optionen in pg_service.conf
[servicename] parameter=value parameter=value ...
Autocommit aus
$db->{AutoCommit} = 0;
Schließen
$db->disconnect;
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";
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 }
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 }
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";
Daten abrufen
$db->{RaiseError} = 1; my @erg = $db->selectrow_array("SELECT COUNT(*) FROM nachrichten"); print "Anzahl Nachrichten: " . @erg[0] . "\n";
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";
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;
Unix
extension=pgsql.so
Windows
extension=pgsql.dll
Verbindungsaufbau
$db = pg_connect("connect string"); if (!$db) { ... Fehlerbehandlung }
Persistente Verbindung
$db = pg_pconnect("connect string"); if (!$db) { ... Fehlerbehandlung }
Verbindung wieder schließen
$ergebnis = pg_close($db);
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";
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);
Ausführen
$statementname = "Adresse"; $ergebnis = pg_execute($db, $statementname, array("O'hare"));
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";
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");
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 }
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 }
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);
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"; }
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
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"; }
Verbindungsaufbau
EXEC SQL CONNECT TO ziel [AS verbindungsname] [USER benutzername];
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];
Kompilieren
ecpg beispiel.pgc cc -lecpg -o beispiel beispiel.c
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;
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;