2016-08-10 9 views
0

Ich entwickle eine CGridView, die ein Kontrollkästchen enthält. Dieses Kontrollkästchen ist aktiviert, wenn das Feld SELECT_PRIV in der nächsten Abfrage Y entspricht.Ist diese vollständige äußere Verbindung korrekt?

Die Abfrage, die ich entwickle, hat zwei Tabellen. Eine davon gehört mir und enthält eine Liste von Objekten in der DB, den Objekttyp und das Projekt, das mit dem Objekt zusammenhängt. Zum Beispiel wird eine Zeile:

ID  OBJECT_NAME  OBJECT_TYPE PROJECT 
--  -----------  ----------- ------- 
1 F_XXX_TEST_FUNCTION  FUNCTION  XXX 
2 F_YYY_BETA_FUNCTION  FUNCTION  YYY 
3 F_ZZZ_FINAL_FUNCTION FUNCTION  ZZZ 

Die andere Tabelle ist eine Oracle-Tabelle: USER_TAB_PRIVS. Jede Zeile dieser Tabelle enthält die Beziehung zwischen jedem Benutzer und jedem Objekt. Wenn beispielsweise ein Benutzer keine Berechtigungen für die F_XXX_TEST_FUNCTION hat, wird er in dieser zweiten Tabelle nicht angezeigt. Auf der anderen Seite wird es erscheinen, wenn ein Benutzer irgendeine Art von Zuschüssen hat.

Beispieldaten:

GRANTEE  TABLE_NAME   PRIVILEGE 
-------  ----------   --------- 
user5 F_XXX_TEST_FUNCTION  SELECT 
user1 F_YYY_BETA_FUNCTION  SELECT 
user5 F_XXX_TEST_FUNCTION  DEBBUG 
user1 F_YYY_BETA_FUNCTION  DEBUGG 
user2 F_ZZZ_TEST_FUNCTION  SELECT 
user4 F_YYY_BETA_FUNCTION  SELECT 

Dann versuche ich, zu berechnen, wenn ein zusätzliches Feld Y oder N nach haben sollte, wenn die Beziehung existiert oder nicht. Wenn es existiert, hat der Benutzer Zuschüsse. Wenn nicht, hat der Benutzer diese Zuschüsse nicht.

Die Tabelle, die Ich mag würde bekommen, ist:

OBJECT_NAME   OBJECT_TYPE PROJECT GRANTEE SELECT_PRIV 
    -----------   ----------- ------- ------- ----------- 
F_XXX_TEST_FUNCTION  FUNCTION  XXX  user1   N 
F_XXX_TEST_FUNCTION  FUNCTION  XXX  user2   N 
F_XXX_TEST_FUNCTION  FUNCTION  XXX  user3   N 
F_YYY_TEST_FUNCTION  FUNCTION  YYY  user1   Y 
F_YYY_TEST_FUNCTION  FUNCTION  YYY  user2   N 
F_YYY_TEST_FUNCTION  FUNCTION  YYY  user3   N 
F_ZZZ_TEST_FUNCTION  FUNCTION  ZZZ  user1   N 
F_ZZZ_TEST_FUNCTION  FUNCTION  ZZZ  user2   Y 
F_ZZZ_TEST_FUNCTION  FUNCTION  ZZZ  user3   N 

Meine Logik sagt: Sie müssen select * from your table, und die eine case tun, die prüft, ob die Beziehung in der Oracle-Tabelle existiert oder nicht. Ich habe einige Parameter, wie Objekttyp, Nutzer gewährt zu überprüfen und nur für execute oder select Zuschüsse suchen, so dass die Abfrage ist diese:

 SELECT OL.OBJECT_NAME, OL.OBJECT_TYPE, OL.PROJECT, UT.GRANTEE, 
       CASE WHEN EXISTS (
      SELECT GRANTEE, TABLE_NAME 
       FROM USER_TAB_PRIVS UTP 
       WHERE UTP.GRANTEE IN ('user1','user2','user3') 
       AND UTP.PRIVILEGE IN ('SELECT','EXECUTE') 
        ) 
       THEN 'Y' 
       WHEN EXISTS (
      SELECT * 
       FROM "V_AWP_OBJECTS_LIST" "O" 
      LEFT JOIN USER_TAB_PRIVS UT 
       ON UT.TABLE_NAME=O.OBJECT_NAME 
       WHERE O.OBJECT_NAME IS NULL 
        ) 
       Then 'N' 
        END AS SELECT_PRIV 
       FROM "V_AWP_OBJECTS_LIST" "OL" 
    Full outer join USER_TAB_PRIVS UT 
       On UT.TABLE_NAME=OL.OBJECT_NAME -- OUTTER 
       WHERE OL.OBJECT_TYPE IN ('FUNCTION') 
       AND UT.GRANTEE IN ('user1','user2','user3') 
       AND UT.PRIVILEGE IN ('SELECT','EXECUTE') 

Das Problem bei dieser Abfrage ist, dass es keine Liste nicht zeigen aller Funktionen in V_AWP_OBJECTS_LIST gespeichert, und die zusätzliche Spalte mit Y oder N in Funktion, wenn der Benutzer gewährt hat oder nicht.

Kann mir jemand helfen? Ich weiß nicht, wie diese Abfrage richtig aufgebaut wird.

+0

Es ist ein bisschen schwer ohne Ihre Daten zu sagen. Übrigens sollten Sie doppelte Anführungszeichen vermeiden - sie tun hier eigentlich keinen Schaden, aber sie helfen auch nicht, und sie sind in der Regel riskant. –

+0

Danke für Ihre Antwort und Ihre Tipps. Jetzt werde ich einige Daten als Beispiel hinzufügen. – Maik

Antwort

1

Also, wenn ich das richtig verstehen, für jede Zeile in v_awp_objects_list, mögen Sie pro in Ihrer IN Klausel aufgeführten Benutzer eine Zeile angezeigt werden: IN ('user1','user2','user3'). Um dies zu tun, müssen Sie zusätzlich eine Art temporäre Tabelle mit der Benutzerliste haben, damit Sie daran teilnehmen können. Aus diesem Grund werden Sie die user_cte bemerken, die SYS.DBMS_DEBUG_VC2COLL verwendet, um eine Liste von Benutzernamen in Zeilen zu konvertieren, die verknüpft werden können.

Andernfalls benötigt die Abfrage nur left join unter user_tab_privs, nicht full outer join. Und es braucht auch eine group by Klausel, um sicherzustellen, dass wir nicht mehr als 1 Zeile pro Funktion/Benutzer-Kombination erhalten. Hoffentlich funktioniert das:

with user_cte(username) as (
    select column_value 
    from table(SYS.DBMS_DEBUG_VC2COLL('user1', 'user2', 'user3')) 
) 
select o.object_name, o.object_type, o.project, u.username, 
     case when count(p.table_name) = 0 then 'N' else 'Y' end as select_priv 
    from v_awp_objects_list o 
    cross join user_cte u 
    left join user_tab_privs p 
    on p.table_name = o.object_name 
    and p.grantee = u.username 
    and p.privilege in ('SELECT', 'EXECUTE') 
where o.object_type = 'FUNCTION' 
group by o.object_name, o.object_type, o.project, u.username 
+0

Danke sstan für Ihre Antwort und Korrekturen. Du verstehst es gut. Jetzt bin ich nicht in meiner Arbeit, aber ich werde es morgen versuchen und Ihnen sagen, ob es funktioniert. Danke nochmal! – Maik

+0

sstan, es funktioniert! Vielen Dank.Ich habe einige Fragen, die ich schätzen würde, wenn Sie antworten, um ein wenig über diese Frage zu lernen: -Die mit clausule ist eine virtuelle Tabelle zu erstellen, aber warum Sie diese Klammern verwenden? - Wie ist der Übergang zwischen der virtuellen Tabelle und der Auswahl? Ich meine, du erstellst zuerst die virtuelle Tabelle und dann machst du die Auswahl und spezifizierst die Kreuzverbindung später. Ich verstehe, dass es wie eine kleine Prozedur ist, oder? -Was ist die Tabelle SYS.DBMS_DEBUG_VC2COLL? Ich denke, dass es eine Tabelle ist, um einige vordefinierte Werte auszuwählen. – Maik

+0

Eine andere Frage: -Die Zählung (p.table_name) funktioniert über die gesamte Tabelle user_tab_privs oder funktioniert über die linke Join-Tabelle Build? Vielen Dank. – Maik

Verwandte Themen