Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Einer SQL Abfrage eine zusätzliche Bedingung hinzufügen (https://www.delphipraxis.net/106720-einer-sql-abfrage-eine-zusaetzliche-bedingung-hinzufuegen.html)

hirnstroem 15. Jan 2008 15:36

Datenbank: MS Access • Version: kA • Zugriff über: ADO

Einer SQL Abfrage eine zusätzliche Bedingung hinzufügen
 
'loha Folks,

der folgenden Abfrage soll eine Zusätzliche Bedingung hinzugefügt werden:

SQL-Code:
SELECT *
FROM
(Room INNER JOIN
  (Floor INNER JOIN
    (DeviceType INNER JOIN    
      (Building INNER JOIN
        (Application INNER JOIN Device ON [Application].[ApplicationID] =[Device].[ApplicationID])
      ON [Building].[BuildingID] =[Device].[BuildingID])
    ON [DeviceType].[DeviceTypeID] =[Device].[DeviceTypeID])
  ON [Floor].[FloorID] =[Device].[FloorID])
ON [Room].[RoomID] =[Device].[RoomID])
WHERE
DeviceType.DeviceType = 'DeviceType';
Die Abfrage liefert sämtliche Geräte aus der Tabelle 'Device' mit dem Gerätetyp 'DeviceType' (sowie sämtliche miteinbezogene Felder).

Nun ist es so, dass es zusätzlich zu den Geräten auch Benutzer gibt. Diese Benutzer haben entweder zugriff auf ein Gerät oder keinen Zugriff. Die Abfrage soll nun so angepasst werden, dass sie nur noch Ergebnisse (Geräte) liefert, für welche der Benutzer der die Abfrage ausführt (dessen UserID etc. ist bekannt) auch zugriff hat. Zudem soll die Möglichkeit bestehen, dass wie bei der obigen Abfrage sämtliche Geräte abgefragt werden können.

Mein Versuch dies zu realisieren sieht folgendermassen aus:

SQL-Code:
SELECT *
FROM
(Room INNER JOIN
  (Floor INNER JOIN
    (DeviceType INNER JOIN
      (Building INNER JOIN
        (Application INNER JOIN Device ON Application.ApplicationID = Device.ApplicationID)
      ON Building.BuildingID = Device.BuildingID)
    ON DeviceType.DeviceTypeID = Device.DeviceTypeID)
  ON Floor.FloorID = Device.FloorID)
ON Room.RoomID = Device.RoomID) INNER JOIN Device_User
ON Device.DeviceID = Device_User.DeviceID
WHERE
DeviceType.DeviceType = 'DeviceType'
AND
((Device_User.UserID = :UserIDIncorporateAccessRights AND Device_User.Access = True) OR :UserIDDoNotIncorporateAccessRights = 0);
Der eine Teil der Bedingung nämlich, dass die Abfrage nur noch Ergebnisse liefert, für welche der Aufrufende Benutzer Rechte hat, wäre hiermit erfüllt indem der Parameter :UserIDIncorporateAccessRights mit der UserID des entsprechenden Benutzers gefüttert wird.

Der andere Teil, dass auch sämtliche Geräte ohne Berücksichtigung der Benutzerrechte, abgefragt werden noch nicht. Übergebe ich dem Parameter :UserIDIncorporateAccessRights einen Wert der nicht zutreffen kann und dem Parameter :UserIDDoNotIncorporateAccessRights den Wert 0 damit die Bedingung zutrifft, so wird das kartesische Produkt gebildet. So ist im Ergebniss also jedes Gerät soviele Male vorhanden, wie es Benutzer in der Datenbank gibt.

Kann ich nun das Ergebnis irgendwie derart filtern, dass ein Gerät nur einmal im Ergebnis vorkommt?

Für etwas Beihilfe bin ich sehr empfänglich und dankbar -.-

Grüsse
hirnstroem

PS: Ich hoffe man versteht, was isch schrieb.

shmia 15. Jan 2008 18:09

Re: Einer SQL Abfrage eine zusätzliche Bedingung hinzufügen
 
Verwende doch 2 Abfragen, je nachdem, ob mit User oder ohne.
Wenn du nur eine Abfrage möchtest, dann kannst du die Abfrage auch dynamisch zur Laufzeit ändern:
Delphi-Quellcode:
if mitUser then
begin
   Query1.SQL.Lines[13] := 'AND ((Device_User.UserID = :UserIDIncorporateAccessRights AND Device_User.Access = True)';
   Query1.Parameters.ParamValues['UserIDIncorporateAccessRights'] := ...  ; // muss der Parametername wirklich so heissen ?
end
else
   Query1.SQL.Lines[13] := '';
Zur Entwurfszeit muss nachtürlich am Ende des SQL-Properties mindestens ein Leerzeile vorhanden sein.

marabu 15. Jan 2008 20:00

Re: Einer SQL Abfrage eine zusätzliche Bedingung hinzufügen
 
Hallo,

spontan würde ich prüfen, ob nicht ein LEFT OUTER JOIN an Stelle eines INNER JOIN eingesetzt werden kann:

SQL-Code:
...
ON Room.RoomID = Device.RoomID) LEFT OUTER JOIN Device_User
ON Device.DeviceID = Device_User.DeviceID
WHERE DeviceType.DeviceType = 'DeviceType'
AND Device_User.UserID = :UserID
AND Device_User.Access = True;
Bei gültiger UserId sollte eine korrekte Selektion stattfinden, bei einer ungültigen sollten alle Werte für Device_User fehlen.

Freundliche Grüße

hirnstroem 16. Jan 2008 08:51

Re: Einer SQL Abfrage eine zusätzliche Bedingung hinzufügen
 
Danke shima und marabu,

der LEFT OUTER JOIN hatte nicht auf Anhieb den gewünschten Effekt, so habe ich jetzt zwei unterschiedliche Abfragen und dies funktioniert erwartungsgemäss wie es soll.

Vielen Dank für die Hilfe
Grüsse
hirnstroem


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz