View oder Tabelle je nach User

Mag sein. Nur, das, was zurück kommt (oder kommen soll) hat eine Tabellenstruktur, und diese muß irknwie bekannt sein.

Dies lässt sich ausführen aber das Abfrageergebnis lautet: ERROR: a column definition list is required for functions returning “record”. Sorry da hört mein Latein auf. Ich würd ja mit Rückgaben arbeiten. Aber bitte sag mir doch mal einer was ich als Rückgabe für eine Abfrage angeben muss.

Guggst Du: PostgreSQL: Re: a column definition list is required for functions returning "record"
Siehst nur auf den ersten Blick spanisch aus :wink:

Wenn ich nun widerum durch die Abfrage latschen muss wie du schon oben beschrieben hast, dann ist das alles umsonst weil ich eine unterschiedliche Anzahl von Spalten habe. Und somit würden wir uns immer im Kreis bewegen.


test=# select * from foo;
 a | b | c
---+---+---
 1 |   | 3
(1 row)

Time: 0.686 ms
test=*# create or replace function abc() returns setof record as $$begin select * from foo; end; $$language plpgsql;
CREATE FUNCTION
Time: 3.803 ms
test=*# select *  from abc() as (a int, b int, c int);
ERROR:  SELECT query has no destination for result data
HINT:  If you want to discard the results, use PERFORM instead.



Naja so ich hoffe das jetzt klar ist wo das Problem liegt. Ich komm auf jeden Fall nicht mehr weiter. Wenn du hier angekommen bist: Nochmal dankeschön

Meinst Du hier?

Vielleicht bin ich auch zu müde, außerdem hab ich grad noch was anderes vor um diese Zeit. Ich versuch morgen noch mal, Dein Problem chronologisch zu erfassen…

Andreas

Vielleicht kommst Du einfach zum Ziel, wenn Du für die Leute aus Y ein eigenes Schema anlegst, in dem der View liegt und diese auch keinen Zugriff auf das Schema mit der Table haben.

Dazu dann halt den Parameter SEARCH_PATH passend setzen:

ALTER ROLE name SET parameter { TO | = } { value | DEFAULT }

Andreas

Guggst Du: > http://archives.postgresql.org/pgsql...1/msg00904.php
Siehst nur auf den ersten Blick spanisch aus :wink:

Stimmt auf den ersten Blick. Und auf den zweiten auch. Ich bezieh mich hier auf die 3. Antwort. Ich denke mal das da die Antwort drinsteht.

regsalida (deptid int, deptname text);

Ich soll so eine Funktion erstellen. Aber was hat die für einen Sinn?

Pero al ver tu funcion veo que devuelves un select * from osea toda la tabla y si es asi te recomiendo que cambias el tipo devuelto de tu funcion a el tipo de la tabla que haces el select RETURNS SETOF record AS cambialo a setof nota(o como se llame tu tabla)

Davon versteh ich auch nichts. Kann einer von euch Spanisch?

declare  resultado record;
cambialo por
declare resultado nota%rowtype;
y debe funcionar

1 ist klar, 2 das ist spanisch, 3 vom sinn her: ich soll resultado (also
ein record) deklarieren mit tabellenname%rowtype , 4 es sollte dann
funktionieren??

2 versteh ich nicht
3 so?? r person%rowtype; Das funktioniert nicht. Syntax error

r tabellename%rowtype funktioniert. Bringt aber nichts gleiche Fehlermeldung.

Ziehe das mal bitte nicht so aus dem Kontext, wo ich die Antwort gab. Ich meinte exakt die Mail, die ich nannte, und auch nicht das dort zitierte, sondern das geschriebene. Ganz konkret, ich habe nur Deine Fehlermeldung an Google verfüttert und u.a. das erhalten. Und ganz konkret meinte ich dies hier:

select * from f_a_prrueba3() as (campo1 int, campo2 varchar(30), etc, etc);

Ich kann kein spanisch, leidlich englisch und a bissl deutsch, aber diese Antwort bezog sich auf:

> > ----------------------------------------------------------------------
> > -------- ERROR : a column definition list is required for functions
> > returning "record"
> > ----------------------------------------------------------------------

Und exakt dieses Problem hattest Du geschildert.


Ich zeigte Dir dann noch einen kleinen Schnellschuß von mir, hier noch einmal:

test=# select * from foo;
 a | b | c
---+---+---
 1 |   | 3
(1 row)

Time: 0.686 ms
test=*# create or replace function abc() returns setof record as $$begin select * from foo; end; $$language plpgsql;
CREATE FUNCTION
Time: 3.803 ms
test=*# select *  from abc() as (a int, b int, c int);
ERROR:  SELECT query has no destination for result data
HINT:  If you want to discard the results, use PERFORM instead.

Da hab ich das, was in der spanischen Mail stand, demonstriert. Und dazu noch die nächste Fehlermeldung, die Du bei Deinem gezeigten Code bekommen wirst, wenn Du das eben behandelte Problem gelöst hast:

ERROR:  SELECT query has no destination for result data
HINT:  If you want to discard the results, use PERFORM instead.

Du willst aber etwas rückgeben, also ‘mußt Du durch das Ergebnis latschen’.

Aber auch, wenn Du das geschafft hast, wirst Du ein Problem haben: Deine Zielstellung, irgend was schwammig formuliertes als Frage der DB vorzuwerfen und je nach Mondphase und Windrichtung was passendes als Antwort zu bekommen, wird so nicht gehen.

Deshalb hatte ich einen neuen Thread gemacht, um ausgehend von der allerersten Frage und dem bisher gesammelten Wissen vielleicht einen Weg aus dem Irrgarten zu zeigen. Schade, daß zwar die letzte Antwort in diesem neuen Thread war, sich aber auf den alten bezog.


Andreas, noch reichlich 1 Woche bis zum Urlaub…

So habe das Problem gelöst. Auf meine Weise aber es funktioniert. Ist vielleicht auch nicht ganz sauber…aber es funktioniert. Meinungen dazu interressieren mich auf jeden Fall. Besonders die von dir Akretschmer. Vielen Dank nochmal für deine Geduld.

Also.
Ich habe:
1 Tabelle person in der alles steht
1 View->Select * from person

Es gibt 2 Gruppen die einen sind Stäbe die anderen Leiter. Leiter dürfen nicht alles von Person sehen, Stäbe aber schon.

Stäbe bekommen Select auf Person
Leiter nicht, aber Select auf die View

Hier mein Script:

CREATE OR REPLACE FUNCTION getperson(OUT peid integer, OUT vorname character varying, OUT nachname character varying, OUT gebdat date, OUT strasse text, OUT plz text, OUT ort text, OUT telnr text, OUT email text, OUT jahrgang integer, OUT geschlecht integer)
  RETURNS SETOF record AS
$BODY$
	declare r record; 
	begin 
		IF has_table_privilege('person', 'select') 
		THEN
			 for r in select * from person 
				loop 
					peid=r.peid;
					vorname=r.vorname;
					nachname=r.nachname;
					gebdat=r.gebdat;
					strasse=r.strasse;
					plz=r.plz;
					ort=r.ort;
					telnr=r.telnr;
					email=r.email;
					jahrgang=r.jahrgang;
					geschlecht=r.geschlecht;
					return next; 
				end loop; 
		ELSE
			for r in select * from person 
				loop 
					peid=r.peid;
					vorname=r.vorname;
					nachname=r.nachname;
					geschlecht=r.geschlecht;
					gebdat=null;
					strasse=null;
					plz=null;
					ort=null;
					telnr=null;
					email=null;
					jahrgang=null;
					return next; 
				end loop; 
		END IF;
	end;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;

Funktioniert.

Ja, ist okay. Man kann sowas im übrigen auch direkt in SQL machen, mit CASE …, und damit einen VIEW erstellen. Aber letztendlich ist das egal. Hättest Du gleich das so klar beschrieben wie oben zitiert, hätte man Dir schneller helfen können.

Andreas

Andreas

Hi nochmal

wollte gerade mal die Sache mit dem case testen so wie du es vor ein paar postings geschrieben hast. Ich denke das ist auch eine interressante Lösung. Mein Problem ist nur ich kann nicht mehr als eine Spalte leer anzeigen lassen. Ich hab mir in der Doku das angeschaut, aber geholfen hat es nichts. Kannst du das hier auch noch schnell posten??

Ganz schnell:

test=*# select * from foo;
 a | b | c
---+---+---
 1 |   | 3
 2 | 3 | 4
 1 | 1 | 1
(3 rows)

Time: 1.381 ms
test=*# select a, case when a =1 then 0 else b end, case when a=1 then 0 else c end from foo;
 a | b | c
---+---+---
 1 | 0 | 0
 2 | 3 | 4
 1 | 0 | 0
(3 rows)

Anstelle der Bedingung a=1 kannst Du Deine Bedingung einsetzen.

Andreas

Hi, hab den Thread mal verfolgt und muss sagen wirklich interessant.

Seh ich das richtig, dass die User dann keine Rechte auf den view oder auf die tabelle haben, sondern “nur” die funktion aufrufen “getperson”?

Zusatzfrage: Kann ich einem Benutzer/gruppe Rechte geben eine Funktion auszuführen?