PL/Perlu (de)

Z PostgreSQL
(přesměrováno z Karlos)
Skočit na navigaci Skočit na vyhledávání

PL/Perlu - unglaubwürdige Perl

Übersetzung von Karel Kovařík

Es ist eine Frage, ob die Datenbank einen Zugriff in der Datenquelle braucht. Entweder auf der Dateiebene oder auf der Anwendungsdienstebene. Warum nicht? Ab diesem Zeitpunkt ist für mich PostgreSQL kein RDBMS (relationale Datenbankmanagementsystem) sondern es wird, in der Hauptsache, einen Anwendungsserver. Worum geht es? Mit anderen Worten: man verscheibt einen Teil des Kodes von "Bussineslage" (nicht interaktiv) unten in der Datenbank. Je mehr reduziert man die Bussinesebene, um so mehr kompliziert man die Datenbankenebene. Mit dieser Schwerpunktverscheibung an erste oder an die andere Lage ändert sich der Arbeitszeitaufwand von dieser Anwendung nicht. Eine gewisse Kodemenge, die diese Problematik löst, musst man schreiben. Und diese Menge ist von Anwendungsarchitektur nicht abhängig.

Eine Bemerkung: was bedeutet der Anwendungsserver?Der Anwendungsserver ist eine Kombination von Software- und Hardwaresmitteln, die die Aktivierung und die Organisierung des Informationstechnologies ermöglicht. Die Anwendungsserver ermöglicht natürlich die Kommunikation zwischen Informationstechnologies (Planung, automatische Starten usw.) Sehr gute Idee (und sie ist nich neueste) ist Benutzung der Anwendungsserverkonzept auch für Kundenanwendung. Das bedeutet, dass diese Anwendungen zwischen sich und mit dem Benutzer kommunizieren. Zum Beispiel: reinakademisches Projekt Oberon, EJB, Zope auf Python-Basis, man kann auch Apache und PHP in diese Kategorie eingliedern.

Es gibt eine Idee: "am wichtigsten sind Daten und Datenfluss". Wenn man diese Idee akzeptiert, kann man sich auch mit den Anwendungsserver auf der Datenbankebene abfinden. Wer weiß, wass alles zum Beispiel mit Data transformation serveces (DTS) Firma Microsoft machen kann...Aber diese DTS ist nich genau Anwendungsserver: MsSQL (Microsoft SQL) hat keinen Zutritt zur externen Quellen (mann musst vbscript und COM benutzen), im Datenbank ist eine Dienstdefinition speichern. DTS projektieren ist in der Datenbankschnittstelle möglich. Datenbank kümmerst sich um DTS-Anlauf und DTS-Überwachung. Firma Microsoft hat eine Zeit die Idee "ales ist Datenquelle" forcieren - mit ADODB ist möglich zu viele Daten wie zu Datenbank herangehen. Zum Beispiel: für Ms Exchange hat sowohl nativ COM-Datenbibliothek als auch ADODB-Steler existiert; es war möglich E-mail durch Anwendungen mit ADODB-Schnittstelle verarbeiten. Etwas wie ADODB gibt in Linux nicht. Man kann ADODB einigermaßen (in PostgreSQL) mit PSI im PL/Perl auswechseln. Perl benutze ich nur wie "Klebstoff" (vbscript-Ähnlichkeit), mit dem man CPAN-Datenmodule vereinigt und mit dem man Moduleingabe und Modulausgabe konvertiert.

Wie soll man den Anwendungsserver aus PostgreSQL machen? Sehr einfach. Aus gespeicherte Unterprogrammprozedur macht man einzelne Anwendung. Diese Anwendung aktiviert man mit der Anweisung SELECT. Parametern, die man mit SELECT integriert, parametrieren die aktivierte Anwendung. Die Ausgabe ist eine Tabelle, ein Datenfeld oder eine Skaliervariable. Warum benutzt man die Anwendungsunktionalität in der gespeicherte Unterprogrammprozedur? Weil in allen Datenbank (Nativprotokoll, ODBC, ADODB usw.) kann man die Anwendung aktivieren. In der Datenbank kann man die Zugriffsrechte einstellen (wer kann die Anwendung aufrufen, welche Daten kann die Anwendung benutzen usw.). Hauptsächlich: man muss sich um das Datenformat nicht kümmern, weil die Datenkompatibilität zwischen Datenbänker und zwischen verschiedenen Plattformen (in den meisten Fällen) kein Problem ist. Die Umschlüsselung und richtige Darstellellung macht die Datebankebene. Und endlich: man kann SQL-Spräche zu der Ausgabeabsiebung und zu der Ausgabeformatierung benutzen. Mögliche Nachteile: vor allem mehr komplizierte Programmentwicklung, bestimmte Unkosten bedingten durch die Umschlüsselung des Ausgabedaten für SQL (verschidenes von den Nativdatentypen des Perl, C). Auch grössere Serverbelastung, kleinere Bellastverteilung auf Klienten oder auf Server mit der "Bussineslage". Endlich grössere Abhängigkeit von der Datenbankplattform.

Perl- und PostgreSQL-kombination trägt mit bestimmte Beeinträchtigung der Nutzung. Diese Beeinträchtigung sind durch bestimmten Unreife bedingt. In hier bezogene Beispielen sind Daten zwischen Perl und PostgreSQL einmalig übertragt (auch im Fall des SRF-funktionen). Wenn der Computer zurück "SETOF record" gibt, dann Funktion in Perl formiert zuerst "Hashenfeld". Dieses "Hashenfeld" enthält die ganze Ergebnisdaten, die in PostgreSQL weitergegeben werden. Dagegen PL/plPGSQL weitergibt Daten je ein Datenregistrierung. Diese Lösung ist für kleinere Tabellen (cca bis 10000 Zeilen). Für grössere Tabellen benutzen Sie "return_next" Function.

CREATE OR REPLACE FUNCTION perl_set()
RETURNS SETOF perltest AS $$
    return_next({ f1 => 1, f2 => 'Hallo', f3 => 'Welt' });
    return_next({ f1 => 2, f2 => 'Hallo', f3 => 'PostgreSQL' });
    return_next({ f1 => 3, f2 => 'Hallo', f3 => 'PL/Perl' });
    return undef;
$$ LANGUAGE plperl

Die Grundlage jedes Anwendungsserver sind Dienste (Anwendungen). Hier beschribene Beispiele haben keinen Einheitscharakter. Ich habe sie für keine konkrete Aufgabe geschrieben, sonder für Möglichkeiten des PL/Perl probieren (oder das Leben und Serveradministration sich leichtmachen). Ich werde sich gern mit Ihre Vorschläge inspiriert. Viele Beispiele kann man auf www.cpan.org finden.

  1. Zugänglichmachung von Benutzerliste des Operationssystem
  2. Zugang zur beliebigen Datei (z.B. zur Prozessliste)
  3. Log-Datenverarbeitung
  4. UUID-gewinnung ("Universally Unique Identifier")
  5. universal Notification über die Datenveränderung durch E-mail
  6. Zugrif zur Prozessorinformation
  7. Zugrif zu den Angaben über PostgreSQL-Prozess
  8. Suche nach Daten in der externen Datenbasis (SOAP /ursprünglich für Simple Object Access Protocol/, Amazon-Basis
  9. Anschluss des Tabelles aus einer anderen Datenbank(mysql via DBI)
  10. Information aus externen Basis entnehmen (http, HTML)
  11. auswechsellbar XML-Erzeugung ausgehend von einer Abfrage
  12. auswechsellbar XML-Einführung

Die meisten Diensten (Anwendungen) habe ich geschrieben, damit ich eine bestimmte Kommunikationsorte in Perl probiere und demonstrierte. Ihre Nutzeffekt ist diskutabel und es ist schwer zu sagen, ob es zum etwas ist. Nützlich finde ich: Zugänglichmachung des Benutzerliste (Administration), Zugang zur beliebigen Datei (Datenimport), universal Notification (Entwicklung), Anschluss des Tabelles aus einer anderen Datenbank (inzwischen langsam, sondern auch ist es Effektivierung des Aktualisieren), XML-Erzeugung

Bei alle (ein bischen) komplizierten Projekte bin ich für Architektur des Anwendungsservers. Und es ist egal, ob wird die Java-Technologie (Tomcat) oder SQL-Technologie (PostgreSQL, Firebird) benutzen. Ich kenne nur PostgreSQL, sodass benutze ich nur diese relationale Datenbank. Java verstehe ich nicht. Schreiben für Tomcat finde ich sehr kompliziert - die Möglichkeiten in Java sind natürlich irgendwo anders. Wesentlich ist die Änderung bei Anwendung entwerfen, bzw. ihre Dekomposition auf interaktive und uninteraktive Datenblöcke und bei implementierung des uninteraktives Teil den maximal Wiedergebrauch benutzen.

Diensten (Anwendungen) basierten auf Datei Parsieren

Es geht um die einfachste Dienstmenge. Nach der Dateiöffnung wird die ganze Zeile verarbeitet. Das Ergebnis kann die Aufnahmentabelle (ein Log, ein Passwort, cpuinfo =Informationen über den Prozessor; ein Status) oder die Wertigkeit (UUID) sein. Ein Eingang können wirkliche Datei (Lod, Passwort), die Pipe (=englisch für Rohr, Röhre; "ps |" Parameter) oder virtuose Datei von /proc/ Namenraum (Status, UUID, cpuinfo). Ob auf dem Quellkode (Computer-Code) etwas um Beachtung steht, dann ist es die Generierung von SETOF-ausgabe. Weiter ist nötig die Informationssicherheit anzusprechen. Deise Dienste sind Gefährlich! Für der Zugriff zu Datensystem ist nötig Untrusted Perl zu benutzen. Der kann nur SuperUser von die Datenbank benutzen. Mit die Lines-Funktion gibt man allen Benutzern die Möglichket die wählbare Datei wie den SuperUser benutzen!

CREATE OR REPLACE FUNCTION ext.rtab(varchar, varchar) RETURNS SETOF RECORD AS $$
   open FILE, $_[0]; my @cntn = ();
   while (<FILE>) { chop; 
      my @items = map {s/^\s+|\s+$//g; $_;}  split ($_[1]);
      my %iitems; @iitems{map 'col'.$_, 0..$#items} = @items;
      push @cntn, \%iitems; }
   close FILE;
   return \@cntn; 
$$ LANGUAGE plperlu;

CREATE VIEW ext.passwd AS SELECT col0 AS account, col1 AS passwd, col2 AS uid,
       col3 AS gid, col4 AS description, col5 AS home,
       col6 AS shell FROM ext.rtab('/etc/passwd',':') 
  AS (col0  varchar, col1 varchar, col2 integer,
      col3 integer, col4 varchar, col5 varchar,
      col6 varchar);

Denken Sie an, dass Programmablauf verläuft auf dem Server, wo sind die Ergebnisse auch zurückgegeben. Darum musst man richtig kodierte Daten genau aus Perl zurückgeben. Befehl SET client_encoding hat für diese Prozedur keinen Sinn. Zum Beispiel, wenn Daten in latin2-Kodierung und Dateibase in UTF-8-Kodierung sind, dann musst man die Prozedur um Umcodieren des einlesener Daten erweitern. Der dritte Parametr ist Kodierung von Eingabedatei.

CREATE OR REPLACE FUNCTION rtab(varchar, varchar, varchar) RETURNS SETOF RECORD AS $$
   use Encode 'from_to';
   my $rv = spi_exec_query("SELECT current_setting('server_encoding')",1);
   my $encoding = lc($rv->{rows}[0]->{current_setting});
   open FILE,$_[0]; my @cntn = ();
   while (<FILE>) { chop;
      from_to($_, $_[2], $encoding);  
      my @items = map {s/^\s+|\s+$//g; $_;}  split ($_[1]);
      my %iitems; @iitems{map 'col'.$_, 0..$#items} = @items;
      push @cntn, \%iitems; }
   close FILE;
   return \@cntn;
$$ LANGUAGE plperlu;

Anschluss des Tabelles aus einer anderen Datenbank

Ich zweifele nicht an Nützlichkeit, trotzdem habe ich sehr kleine Effektivität erwähnen. In diesem Zeitpunkt haben die PostgreSQL-Anwender keine andere Möglichkeit, wie mit "Unpostgresql" Datenbänker arbeiten. Mit Perl und seiner Schnittstelle ist einfach sich zu Oracle, MsSQL, mySQL, Informix, Firebird anschließen (man musst nur DNS abendern /= Abkürzung zu Domain Name System/). Haleluja. Benützung von dieser Prozedur kann das Ende von Dump- und Import-cyklus bedeuten, damit man Daten aus keine Postgre RDBMS (relationale Datenbankmanagementsystem) in PostgreSQL bekommt (und Dump kann im bestimmtes Format für einige Datenbänker sehr kompliziert werden). Zum Beispiel - die DBI (Database Independent) unterstützt: ADO, CSV, DB2, Informix, Oracle, ODBC, Sybase, XBase (ADO pouze na win32), JDBC, LDAP, MySQL, MaxDB, SQLLite, Solid. Klare Nachteil ist die Geschwindigkeit, es taugt zu grossen Schlussdatenmenge nicht (roadmap DBI auf drittes Optimisationplatz fetchrow_hashref). Nur Workflow ist noch nicht fertiggemacht.

CREATE OR REPLACE FUNCTION ext.rmysql(varchar, varchar, varchar,
  varchar) RETURNS SETOF RECORD AS $$
   use DBI;
   my $dbh = DBI->connect('dbi:mysql:'.$_[0],$_[1],$_[2], 
      { RaiseError => 1, AutoCommit = > });
   $dbh->do("set character_set_results='latin2'");
   my $sth = $dbh->prepare($_[3]);
   $sth->execute(); my $myref; 
   while ($dat = $sth->fetchrow_hashref) {push @$myref, $dat; }
   $sth->finish(); $dbh->disconnect();
   return $myref;
$$ LANGUAGE plperlu;

CREATE VIEW ext.Namen AS SELECT * FROM ext.rmysql('instalace:Schmutzfink','dbuser','****',
  'SELECT ixKontakt, Vorname, Familienname, Titel, email, Telefonnummer FROM Kontakt') AS
  (ixKontakt integer, Vorname varchar, Familienname varchar, 
   Titel varchar, email varchar, Telefonnummer varchar);

Suche nach Daten in der externen Datenbasis

Ich habe Zwei Diensten (Anwendungen) geschrieben. Die Erste kann aus dem NIC-Web Angaben über Domäne erwerben, die Andere sucht Amazons Publikationen auf der Grundlage von Schlüsselworte. Das Ergebnis von beiden Diensten (Anwendungen) ist eine Tabelle. Beachten Sie, wie ist die erste Dienst (Anwendung) kompliziert. Erwerben Daten aus klassisches HTML-Formular ist mehr kompliziert als eine benutzung des SOAP (für Verarbeitungvereinfachung ist die Datenbibliothek WWW::Mechanize benutzen /primär für automatisch Formularausfühlung - Selbsterprobung, Automatisierung des Anderes/ und Datenbibliothek HTML::TreeBuilder für Überführung HTML-Tabelle in 2D-Feld). SOAP ist optisch länger, überträgt mehr Parametern. Modul WWW::Mechanize würde ich hauptsächlich für Angabe in Externen Basen benutzen (z.B. Trigger, ausfühlung des Registrierungformular)

CREATE OR REPLACE FUNCTION ext.amazon_search(varchar) RETURNS SETOF ext.amazon_lst AS $$
   my $dev_token='insert developer token'; my $af_tag='insert associate tag';
   my $amazon_wdsl = "http://soap.amazon.com/schemas2/AmazonWebServices.wsdl";
   use strict; use SOAP::Lite; my @listbooks = (); 

   my $amazon_search = SOAP::Lite->service("$amazon_wdsl");
   my $results = $amazon_search ->

      KeywordSearchRequest(SOAP::Data->name("KeywordSearchRequest")
         ->type("KeywordRequest")
            ->value(\SOAP::Data->value(
                SOAP::Data->name("keyword" => $_[0]), SOAP::Data->name("page" => "1"), 
                SOAP::Data->name("mode" => "books"), SOAP::Data->name("tag" => $af_tag), 
                SOAP::Data->name("type" => "lite"), SOAP::Data->name("devtag" => $dev_token),))
   );

   foreach my $result (@{$results->{Details}}){
      $result->{UsedPrice} =~ s/\$//g;
      push @listbooks, {
         productname => $result->{ProductName}|| "no title", 
         authors => "{".join (', ', @{$result->{Authors}}) . "}",
         price => $result->{UsedPrice},asin => $result->{Asin}}}
   return \@listbooks;
$$ LANGUAGE plperlu;

SELECT * FROM ext.amazon_search('xml perl');

plperlu=# SELECT productname, authors FROM ext.amazon_search('postgresql');
                      productname                      |                    authors                     

-------------------------------------------------------+------------------------------------------------
 Beginning Databases with PostgreSQL                   | {"Richard Stones","Neil Matthew"}
 PostgreSQL                                            | {"Korry Douglas","Susan Douglas"}
 PHP and PostgreSQL Advanced Web Programming           | {"Ewald Geschwinde","Hans-Juergen Schoenig"}
 PostgreSQL Developer's Handbook (Developer's Library) | {"Ewald Geschwinde","Hans-Juergen Schoenig"}
 PostgreSQL Essential Reference                        | {"Barry  Stinson","Barry Stinson"}
 PostgreSQL: Introduction and Concepts                 | {"Bruce Momjian"}
 PostgreSQL                                            | {"Jeff Perkins"}
(7 rows)

plperlu=# SELECT * FROM ext.read_nic('jetspeed.cz');
-[ RECORD 1 ]+-----------------------------------------------------------------
Domain       | jetspeed.cz
Beschreibung |
Zustand      | Domain ist bezahlt und ist in .CZ
Klebstoff    | {"A - ns.inway.cz","A - ns.inway.net"}
Schlüssel    |
registriert  | 2004-03-09
Expiration   | 2005-03-09
Registrator  | {{REG-GENERAL-REGISTRY,"GENERAL REGISTRY, s.r.o.",2004-11-13, },
             |  {REG-INWAY,"InWay, a.s.",2004-03-09,"2004-11-13 10:25"}}
Besitzer     | {{IWS-PAVEL_STEHULE,"Ing. Pavel Stehule",2004-03-09, }}
techspr      | {{INWAY-TECH,"InWay, a. s.",2004-03-09, }}

Universal Notification über die Datenveränderung durch E-mail

Ich weiß nicht, wie ist diese Dienst sinnvoll. Sie kümmert sich um die Notification des Datenveränderung durch E-amil. Die veränderte Daten sind im XML-Format wie E-mailanlage. Es ist nur wie Beispiel des auswechselbares Trigger in PL/Perl, der mit beliebige Tabelle arbeiten kann (integrieren durch Hashtabelle ist kein Problem),

if ($_TD->{event} eq 'INSERT') {
   foreach $key (keys %{$_TD->{new}}) {
      my $knode = $doc->createElement($key);
      $row->appendChild($knode);
      if (defined($_TD->{new}{$key})) {
        $knode->appendChild($doc->createTextNode($_TD->{new}{$key}));
      } else {
         $knode->setAttribute('null','true');
      }
   }
}

und der Beispiel von E-mailerstellung und sein Absenden:

$msg = MIME::Lite->new (From => $_TD->{args}[0], To => $_TD->{args}[1],
   Subject => $_TD->{args}[2], Type =>'multipart/mixed');
$msg->attach (Encoding => 'binary', Type => 'TEXT; charset=iso-8859-2',
   Data => "In der Dateibase: $dbname trat in $activated Dateienwende ein .\n" .
           "Detaillierte Änderungenbeschriebung ist im E-mailanlage im XML-Format");
$msg->attach(Type => "text/xml; charset=$encoding", Data => $doc->toString,
   Disposition => 'attachment', Filename => 'change.xml');   

$msg->send_by_sendmail();

XML-Erzeugung, XML-Verarbeitung

XML ist Format, der von die ganze Datenbank unterstützt würde. Spezifikation SQL/XML PostgreSQL erfüllt nicht (ich weiß nur über Datenbank2, die unterstützt sie ganz) und wahrscheinlich werde noch Zeitlang nicht (bestimte Förderung - Zugänglichmachung libXML2 - ist in den Nachträgen (contrib)). Perl hat gut Teil größer Möglichkeiten und es ist natürlich ihm benutzen. Es geht, vor allem, um XML-Erzeugung. Wenn die Datenbank den universalen XML zusammenzustellen imstand sind. Dann ist möglich die Anwendungsebene vereinfachen. Die Tabellebildung (und das ist der Aufgabenschwerpunkt der Datenbank-Applikation) beschränkt sich auf die Absendung des SQL-Befehl und auf nachfolgende Transformation XML in der Tabelle mit der Hilfe von XSLT (einfachere Variante auf der Client-Seite oder komplizierte Variante auf der Server-Seite). Aktuell CPAN XML::generator::DBI unterstützt Stile nicht, es ist notwendig Patch benutzen:

55a56,59
>     if (defined($proxy->{Stylesheet})) {
>        $proxy->SUPER::processing_instruction( {Target => 'xml-stylesheet',

>      Data => "type='text/xsl' href='$proxy->{Stylesheet}'"});
>     }

CREATE OR REPLACE FUNCTION ext.xml(varchar, varchar) RETURNS text AS $$
   use DBI;
   use XML::Generator::DBI;
   use XML::Handler::YAWriter;
   my $rv = spi_exec_query("SELECT current_setting('client_encoding'), " .
                           "current_database()", 1);
   my $encoding = lc($rv->{rows}[0]->{current_setting});
   my $cdb = $rv->{rows}[0]->{current_database};
   my $dbh = DBI->connect ("DBI:Pg:dbname=$cdb", "", "", { RaiseError => 1, PrintError => 0});
   my $ya = XML::Handler::YAWriter->new (Encoding=>$encoding, 
        Pretty => {PrettyWhiteNewline => 1, PrettyWhiteIndent => 1,});
   my $gen = XML::Generator::DBI->new (Handler => $ya, dbh => $dbh,
                                       ByColumnName => 1, ShowColumns => 1,
                                       Stylesheet => $_[1],);
   $gen->execute ($_[0]); $dbh->disconnect ();
   return join('',@{$ya->{Strings}});
$$ LANGUAGE plperlu;
SELECT ext.xml('SELECT * FROM ext.Namen LIMIT 10','x01.xsl');

Php skript:

require("common.inc");
header('Content-type: text/xml');
header('');
echo getSkalar("SELECT ext.xml('SELECT * FROM ext.cpu','x01.xsl')");
pg_close($cnh);

x01.xsl ist ein universales XSL-Skript, d.h. für beliebig XML erzeugnet (generiert) von etx.xml-Funktion. Das Ergebnis von der Transformation können Sie am Screenshot betrachten

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<style type="text/css">
BODY      {font-family:Arial,sans-serif; font-size:8pt; font-weight:100; margin-top:0; margin-left:6; margin-right:0}
TD        {font-family:Arial,sans-serif; font-size:8pt; font-weight:100;}
TH        {font-family:Arial,sans-serif; font-size:12px; font-weight:bold; text-align:left}
.r1      {background-color:#E9F2F2; cursor:hand; xline-height:17px;}
.r0      {background-color:#C9E5E7; cursor:hand; xline-height:17px;}
.colhead {color:white; padding-right:0; cursor:hand;
          background-color:#003366; height:12; 
          text-align:left; font-weight:bold; border-top:1px solid white; border-right:1px solid white;}

</style>
</head>
<body>
<table cellspacing="1" cellpadding="2">
  <tr class="colhead">
  <xsl:for-each select="database/select/columns/column/name">
    <th><xsl:value-of select="text()"/></th>

  </xsl:for-each>
  </tr>
  <xsl:for-each select="database/select/row">
    <tr class="r{position() mod 2}">
        <xsl:for-each select="*">

      <td><xsl:value-of select="text()"/></td>
        </xsl:for-each>
    </tr>

  </xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

In der Gegenstellung (Parsen) können wir XML-Dokument wie einen Wert (Inhalt sind strukturierte Daten), z.B. Evidenz von Kommunikation mit SOAP; oder wie eine Tabelle bekommen. In jedem Fall können wir sich das Arbeit erleichtern. Die Validierung der Datenstruktur und der Wert überlassen wir nach DTD (oder XML-Schema) und wir lösen nur Einlesen den Werten. Angewandte XML-Parser unterstützt nur ISO-8859-2 Kodierung oder windows-1250 Kodierung, bzw. verkennt Synonyma von Namen. Wenn man ein Dokument mit anderen Kodierung bekommne kann, dann musst man neue "Map" bilden - Befehlen: make_encmap und compile_encoding. Oder anderen Parser benutzen.

CREATE OR REPLACE FUNCTION ext.rxml(varchar) RETURNS SETOF RECORD AS $$
   use XML::Parser; use Encode;
   my %rec; my @tref = ();
   my $parser = new XML::Parser (
      Handlers => {
         Start => sub {
        my ($p, $tag) = @_; 
            if ($tag eq "row" && $p->depth==2) { %rec = ();}},
         End   => sub {
            my ($p, $tag) = @_;
            if ($tag eq 'row') {push @tref, +{ %rec }; }},
         Char  => sub {
            my ($p, $data) = @_; 
            my $tag = $p->current_element ();
            if ($p->depth == 4) {
               chomp $data; $data =~ s/\^s+|\s+$//g;
               $rec{$tag} .= encode("iso-8859-2", $data) if $data ne "";}}, 
      });
   $parser->parsefile ($_[0]);
   return \@tref;
$$ LANGUAGE plperlu;

CREATE VIEW ext.xmlj AS SELECT * FROM ext.rxml('/tmp/namen.xml') AS (
  ixKontakt integer, Vorame varchar, Familienname varchar, 
  Titel varchar, Email varchar, Telefonnummer varchar);

Dieser Text habe ich im Rahmen von Zwischenprüfung aus Datenbanksystem übersetzt. Zwar habe ich 6 Jahren Hochdeutsch gelernt, aber ich habe ab 2006 Deutsch praktisch nicht gesprochen. Viele Wörter habe ich auf google.com oder auf Deutsche wikipedia gefunden. Bitte entschuldigen Sie meine Fehler ;)