Hash in Klartext?

Fragen, Probleme etc. zu den prozedularen Sprachen ( PL/Tcl, PL/Perl und PL/Python).
sly
Neuer Benutzer
Beiträge: 20
Registriert: Di 5. Okt 2010, 14:52

Hash in Klartext?

Beitrag von sly » Mo 25. Okt 2010, 17:26

Hallo,
wenn ich in PL/Perl eine SELECT Abfrage formuliere, die einen boolean zurückgeben sollte, dann bekomme ich "HASH(0x9a70578)" zurück.

Wie komme ich an "den Kern des Ganzen"? Oder habe ich hier eine riesige Verständnislücke?

Bin gerade dabei plperl zu lernen/verstehen.

Die Abfrage lautet:

my $sel = spi_exec_query("SELECT ST_INTERSECTS(x.first_set,y.second_set) FROM
(SELECT poly AS first_set FROM polys WHERE id=$eins) AS x,
(SELECT poly AS second_set FROM polys WHERE id=$zwei) AS y;");

ST_INTERSECTS ist eine von postgis bereitgestellte Funktion. poly ist eine Tabelle mit einer Spalte voller Polygone (polys).

Die Abfrage soll mir sagen, ob sich zwei überlappen oder nicht?

Für Hilfe wäre ich sehr dankbar.

ads
Erfahrener Benutzer
Beiträge: 4148
Registriert: Mi 8. Feb 2006, 10:58
Wohnort: MD
Kontaktdaten:

Beitrag von ads » Mo 25. Okt 2010, 19:34

Nun, und wie sieht der Rest vom Code aus, der das "ARRAY" produziert?
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support

sly
Neuer Benutzer
Beiträge: 20
Registriert: Di 5. Okt 2010, 14:52

Beitrag von sly » Di 26. Okt 2010, 12:42

Unten habe ich die ganze Funktion angehängt. Ich würde mir gerne das Ergebnis des SELECT als boolean zurückgeben lassen.

Code: Alles auswählen

CREATE OR REPLACE FUNCTION ueberschneidung(INTEGER, INTEGER)
RETURNS boolean
AS
$$

my $ueber = false;
my $eins = $_[0];
my $zwei = $_[1];

elog(NOTICE,"ausgabe: $eins");
elog(NOTICE,"ausgabe: $zwei");

my $sel = spi_exec_query("SELECT ST_INTERSECTS(x.first_set,y.second_set) FROM
(SELECT poly AS first_set FROM polys WHERE id=$eins) AS x,
(SELECT poly AS second_set FROM polys WHERE id=$zwei) AS y;");

elog(NOTICE,"select: $sel");

my $status = $sel->{status};
my $nrows = $sel->{processed};
elog(NOTICE,"status: $status");
elog(NOTICE,"nrows: $nrows");

my $row = $sel->{rows}[0];
elog(NOTICE,"row: $row");


return $ueber;

$$
LANGUAGE plperl;

SELECT * FROM ueberschneidung(1,2);

ads
Erfahrener Benutzer
Beiträge: 4148
Registriert: Mi 8. Feb 2006, 10:58
Wohnort: MD
Kontaktdaten:

Beitrag von ads » Di 26. Okt 2010, 13:57

In $sel steht erst mal nur das Ergebnis der Anfrage drin. Du musst auf die einzelnen Zeilen des Ergebnisses zugreifen.

Hier ein Beispiel:

Kapitel 10 - Serverseitige Programmierung [PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler]
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support

sly
Neuer Benutzer
Beiträge: 20
Registriert: Di 5. Okt 2010, 14:52

Beitrag von sly » Di 26. Okt 2010, 14:56

ok, das klingt plausibel. Ich dachte allerdings das tue ich durch folgenden Befehl

Code: Alles auswählen

my $row = $sel->{rows}[0];
elog(NOTICE,"row: $row");



Und da lautet dann eben die Antwort:

Code: Alles auswählen

psql:test.pl:71: HINWEIS:  status: SPI_OK_SELECT
psql:test.pl:71: HINWEIS:  nrows: 1
psql:test.pl:71: HINWEIS:  row0: HASH(0x9a70080)
psql:test.pl:71: HINWEIS:  row1:


In dem link wird ja auf "Seite 366" explizit auf "daten" zugegriffen. Leider liefert meine Select-Anfrage aber keinen Spaltennamen wie "daten". Wie kann ich denn bei der ST_INTERSECT Funktion drauf zugreifen. Das verstehe ich leider nicht. Kannst Du es mir bitte näher erläutern?

ads
Erfahrener Benutzer
Beiträge: 4148
Registriert: Mi 8. Feb 2006, 10:58
Wohnort: MD
Kontaktdaten:

Beitrag von ads » Di 26. Okt 2010, 15:26

Du könntest deine Ergebnisse mit Namen versehen:

Code: Alles auswählen

SELECT ST_INTERSECTS(x.first_set,y.second_set) AS spalte1


Und $row ist letztendlich nur wieder ein Zeiger auf ein Array. Du musst also da drin noch auf den passenden Schlüssel zugreifen.

Wenn du die untrusted Version von pl/Perl verwendest (das wäre "plperlu"), könntest du mittels dem Modul Data: :D umper in die jeweiligen Variablen hineinschauen.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support

sly
Neuer Benutzer
Beiträge: 20
Registriert: Di 5. Okt 2010, 14:52

Beitrag von sly » Di 26. Okt 2010, 15:32

vielen, vielen Dank. Das benenne mit AS klappt wunderbar, denn dann habe ich ja einen "Namen" auf den ich zugreifen kann. plperlu werde ich im Hinterkopf behalten. Als Neuling in Datenbanken & co war mir das Attribut untrusted zu abschreckend. So nach dem Motto "wer nicht weiß was er tut sollte lieber die Finger...."

ads
Erfahrener Benutzer
Beiträge: 4148
Registriert: Mi 8. Feb 2006, 10:58
Wohnort: MD
Kontaktdaten:

Beitrag von ads » Di 26. Okt 2010, 15:39

In dem Fall empfehle ich dir mal die Dokumentation zu CREATE LANGUAGE. Dort werden die Unterschiede zwischen trusted und untrusted Sprachen dargestellt.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support

sly
Neuer Benutzer
Beiträge: 20
Registriert: Di 5. Okt 2010, 14:52

Beitrag von sly » Mo 1. Nov 2010, 14:51

Ist es möglich die Funktion - wenn sie einmal angelegt ist - auch "direkt" aufzurufen. Also innerhalb einer anderen plperl Funktion nur über den Namen und Attribute? Würde es gerne in einer if-Abfrage nutzen.

Oder grundsätzlich auch aus anderen plperl Funktionen heraus nur in der Form

Code: Alles auswählen

my $sel = spi_exec_query("SELECT * FROM ueberschneidung($i,$j);");
my $sel0 = $sel->{rows}[0]->{ueberschneidung};
if($sel0 eq t)
Finde das etwas umständlich. Direktes auswerten in der Form

Code: Alles auswählen

if(ueberschneidung(X,Y) == true)
wäre eleganter. Ist das irgendwie möglich? Ich gebe zu, mein Verständnis von dem prozeduralen Ansatz scheint sich noch in Grenzen zu halten.

ads
Erfahrener Benutzer
Beiträge: 4148
Registriert: Mi 8. Feb 2006, 10:58
Wohnort: MD
Kontaktdaten:

Beitrag von ads » Mo 1. Nov 2010, 14:56

Nein. Die Funktionen sind ja nur innerhalb der Datenbank bekannt.

Was du allerdings machen könntest: deine in der Datenbank erstellte Funktion ist bloß ein Wrapper über deine eigentliche Funktion.
Die richtige Funktion stellst du dann in einem Modul bereit und rufst sie wahlweise aus Perl heraus oder aus dem Wrapper aus der Datenbank heraus auf.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support

Antworten