Dies ist eine statische Kopie unseres alten Forums. Es sind keine Interaktionen möglich.
This is a static copy of our old forum. Interactions are not possible.

DrChaotica

Senior Schreiberling

  • "DrChaotica" is male
  • "DrChaotica" started this thread

Posts: 714

Date of registration: Jan 22nd 2005

Location: SHG

Occupation: SW-Entwickler

1

Saturday, June 17th 2006, 5:10pm

Sql 8

Mhh, mit A4 habe ich ein paar Probleme... wie finde ich die User, welche mir Leserechte für Tabelle rating2 gewährt haben?

Nach Musterlösung für Übung5, A3 b) konnten diejenigen mit INSERT-Rechten so gefunden werden:

Anfrage 1)
SELECT owner AS "user"
FROM all_col_privs_recd p JOIN
all_col_privs_recd r USING (table_name, owner, privilege)
WHERE table_name = 'RATING2' AND privilege = 'INSERT'
AND p.column_name = 'PERSON' AND r.column_name = 'RATING';

Prima, damit finde ich alle. (Sogar mehr als alle, weil das DISTINCT owner fehlt ;) )

Dasselbe nochmal analog für die Leserechte:

Anfrage 2)
SELECT owner AS "user"
FROM all_col_privs_recd p JOIN
all_col_privs_recd r USING (table_name, owner, privilege)
WHERE table_name = 'RATING2' AND privilege = 'SELECT'
AND p.column_name = 'PERSON' AND r.column_name = 'RATING';

Hier finde ich leider gar keinen mehr.
Nehme ich mir nun die Leute aus der Anfrage 1) heraus, und versuche die Spalten der rating2 zu lesen, klappt das zwar sehr oft, aber bei manchen auch nicht. In dem Fall bekomme ich eine Exception "Unzureichende Leserechte" (oder so ähnlich) zurück.

Das ist insgesamt eine ziemlich blöde Situation ... man könnte noch versuchen, diese Exception abzufangen, und dann diejenigen rating2-Tabellen ohne Leserechte auslassen, aber so superelegant ist das auch nicht. Wie seid Ihr hierbei vorgegangen, Tipps 8) ?

PS: Wo ich gerade bei Tipps bin: Wollt ihr fremde rating2-Tabellen auslesen, öffnet sie mit "username".rating2. Hintergrund: hanspeter.rating2 z.B. lässt sich ohne die Anführungszeichen auslesen, Matrikelnummerusernamen nicht, dies geht nur durch SELECT * FROM "123456".rating2.

PPS: Ich sehe gerade, das stimmt so allgemein gar nicht...man muß Matrikelnummerusernamen mit Anführungszeichen öffnen, bei normale Namen aber dürfen diese Zeichen nicht stehen. Anscheinend sollte man vorher auch noch überprüfen, ob der username eine Zahl darstellt... kennt jemand zufällig die SQL-Funktion hierfür?

This post has been edited 3 times, last edit by "DrChaotica" (Jun 17th 2006, 5:23pm)


XAX

Junior Schreiberling

  • "XAX" is male

Posts: 207

Date of registration: Dec 25th 2004

2

Saturday, June 17th 2006, 5:35pm

In all_col_privs_recd stehen die Zugriffsrechte für Spalten, du willst aber wissen auf welche Tabellen du zugriff hast also brauchst du nur: ALL_TAB_PRIVS_RECD

Hab aber auch ein Problem bei der Aufgabe
"Öffnen Sie dann einen schwach typisierten („weaklytyped“) Cursor für die RATING2-Tabelle jedes solchen Benutzers."
Das müsste man doch mit einen parametrisierten Cursor machen, nur wie geht das wenn ich SYS_REFCURSOR benutzen soll?

This post has been edited 1 times, last edit by "XAX" (Jun 17th 2006, 5:36pm)


derda17

Zuhörer

  • "derda17" is male

Posts: 3

Date of registration: May 7th 2006

3

Saturday, June 17th 2006, 5:56pm

Quoted

PPS: Ich sehe gerade, das stimmt so allgemein gar nicht...man muß Matrikelnummerusernamen mit Anführungszeichen öffnen, bei normale Namen aber dürfen diese Zeichen nicht stehen. Anscheinend sollte man vorher auch noch überprüfen, ob der username eine Zahl darstellt... kennt jemand zufällig die SQL-Funktion hierfür?


vielleicht mit "" öffnen und bei einem fehler in der Exception dann ohne?


ich hab folgendes Problem:
FOR recordle IN (
SELECT distinct owner
FROM ALL_TAB_PRIVS_RECD
WHERE table_name = 'RATING2' and PRIVILEGE='SELECT')
LOOP
DBMS_OUTPUT.PUT_LINE(recordle.owner);
END LOOP;

bekomme Ich ganze 3 owner ausgegeben, die Anfrage an sich liefert aber 91. wo verstecken sich die anderen 88? ?(

XAX

Junior Schreiberling

  • "XAX" is male

Posts: 207

Date of registration: Dec 25th 2004

4

Saturday, June 17th 2006, 6:16pm

du musst deine prozedur mit AUTHID CURRENT_USER IS
erzeugen
ohne bekomme ich auch nur 3 namen ausgegeben

DrChaotica

Senior Schreiberling

  • "DrChaotica" is male
  • "DrChaotica" started this thread

Posts: 714

Date of registration: Jan 22nd 2005

Location: SHG

Occupation: SW-Entwickler

5

Saturday, June 17th 2006, 8:38pm

Quoted

Original von XAX
In all_col_privs_recd stehen die Zugriffsrechte für Spalten, du willst aber wissen auf welche Tabellen du zugriff hast also brauchst du nur: ALL_TAB_PRIVS_RECD

Hab aber auch ein Problem bei der Aufgabe
"Öffnen Sie dann einen schwach typisierten („weaklytyped“) Cursor für die RATING2-Tabelle jedes solchen Benutzers."
Das müsste man doch mit einen parametrisierten Cursor machen, nur wie geht das wenn ich SYS_REFCURSOR benutzen soll?


Danke für den Hinweis, darauf wäre ich so schnell doch nicht gekommen, weil ich in eine andere Richtung gedacht habe. Zu SYS_REFCURSOR, den mußt du nicht unbedingt verwenden, die Aufgabe schlägt die Verwendung dieses Typs ja nur vor.
Die Benutzertabellen durchspulen könntest du z.B. so:

CREATE OR REPLACE PROCEDURE collect_all_rating2
AUTHID CURRENT_USER
IS
TYPE ref_ctype IS REF CURSOR; /* "weakly typed cursor..." */
rating2_csrvar ref_ctype;
rating2_record rating2%ROWTYPE;
sql_stmt VARCHAR2(200);
BEGIN

/*Ein Statement vorbereiten*/
sql_stmt := 'SELECT username, person, rating FROM :1';

/*Implizit definierten Cursor verwenden um alle User aufzulisten, die Zugriffsrechte auf ihre Rating2-Tabelle gewährt haben*/
FOR other_users_record IN (SELECT distinct owner
FROM ALL_TAB_PRIVS_RECD
WHERE table_name = 'RATING2' and PRIVILEGE='SELECT')
LOOP
/*Jetzt die rating2 - Tabelle des jeweiligen durch 'other_users_record.owner' spezifizierten Users öffnen und bearbeiten*/
OPEN rating2_csrvar FOR sql_stmt USING ('"'||other_users_record.owner||'"'||'.rating2');
LOOP
FETCH rating2_csrvar INTO rating2_record;
EXIT WHEN rating2_csrvar%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(rating2_record.person);
END LOOP;
CLOSE rating2_csrvar;
END LOOP;

END;

This post has been edited 3 times, last edit by "DrChaotica" (Jun 17th 2006, 8:44pm)


cst

Praktikant

  • "cst" is male

Posts: 24

Date of registration: Jun 1st 2005

Location: Wunstorf

6

Monday, June 19th 2006, 2:06pm

Die Version von derda17 sieht gut aus, nur fehlt -- wie richtig bemerkt -- das "AUTHID CURRENT_USER". (Sonst bekommt man nämlich nur die 3 Leute raus, die allen (also dem PUBLIC-Benutzer) die Rechte gegeben haben.)

Man muss nicht unbedingt einen Cursor vom Typ SYS_REFCURSOR benutzen, ich hätte aber erwartet dass es zumindest ohne einen weakly typed Cursor garnicht funktioniert... bin auf andere Lösungen gespannt.

Um jeden Benutzernamen Anführungszeichen zu setzen ist ein sehr guter Tipp!!
Und nochwas: Für die Aufgabe muss man keine Bind-Variablen (':1' o.ä.) benutzen; geht auch einfach, indem man sich eine Anfrage als Zeichenkette zusammenbaut -- wenn man denn überhaupt dymanisches SQL braucht.

masjanja

Praktikant

  • "masjanja" is female

Posts: 4

Date of registration: May 27th 2006

7

Tuesday, June 20th 2006, 6:30pm

Hallo!

Der Block von DrChaotica:
OPEN rating2_csrvar FOR sql_stmt
USING('"'||other_users_record.owner||'"'||'.rating2');
funktioniert bei mir nicht. Ich bekomme den Fehler:
ORA-00903: invalid table name
Klappt das bei jemandem?

XAX

Junior Schreiberling

  • "XAX" is male

Posts: 207

Date of registration: Dec 25th 2004

8

Tuesday, June 20th 2006, 7:44pm

Nö das geht nicht, du musst sowas in der Art benutzen:
sql_stmt := 'SELECT username, person, rating FROM "'|| rating_tab.owner ||'"'||'.rating2';

DrChaotica

Senior Schreiberling

  • "DrChaotica" is male
  • "DrChaotica" started this thread

Posts: 714

Date of registration: Jan 22nd 2005

Location: SHG

Occupation: SW-Entwickler

9

Wednesday, June 21st 2006, 5:25pm

Das ist ja seltsam, am Montag ging es noch EXAKT so ?( Naja, was solls, NUN ;) klappt es wie mein Vorposter schon schrieb noch ohne Bind-Variable.
Vorsicht, die Testausgabe dauert sehr lange (ca. 3/4 Minute), in der Zeit nichts machen, sonst hängt Squiggle sich auf...

sql_stmt := 'SELECT username, person, rating FROM ';
OPEN rating2_csrvar FOR (sql_stmt || '"' || other_users_record.owner|| '".rating2');

...oder auch gleich nur: OPEN rating2_csrvar FOR ('SELECT username, person, rating FROM "' || other_users_record.owner|| '".rating2');

This post has been edited 1 times, last edit by "DrChaotica" (Jun 21st 2006, 5:27pm)