Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Firebird View inner join (https://www.delphipraxis.net/175908-firebird-view-inner-join.html)

Perlsau 28. Jul 2013 17:06

Datenbank: Firebird • Version: 2.5 • Zugriff über: IbDac

Firebird View inner join
 
Hallo Fachleute,

ich muß ein wenig ausholen, um mein kleines Problem zu schildern:

Gegeben ist eine Firebird-Datenbank mit einer Log-Tabelle. In dieser Tabelle gibt es einmal eine Spalte Benutzer, die einen Index auf den Benutzernamen (IDX_BENUTZER) der Tabelle BENUTZER enthält. Dann gibt es in der Log-Tabelle aber noch eine weitere Spalte, die ebenfalls einen Index auf den Benutzernamen der Tabelle BENUTZER enthält. Etwas anschaulicher:
Code:
Tabelle USER_LOG

   IDX_USER_LOG : Integer (Autowert)
   BENUTZER     : INTEGER;
   ZIELUSER     : INTEGER;
... und noch ein paar weitere Spalten, die hier aber nicht relevant sind ...
In den beiden Spalten sind logischerweise auch verschiedene Indizes abgelegt (nicht immer, aber immer öfter).

Für des Administrators Überblick benötige ich eine Grid-Darstellung, in der nicht nur die Benutzer-Indizes dargestellt werden, sondern die Benutzernamen. Die holte ich mir via Lookupfeld aus der Benutzertabelle:
Code:
Tabelle BENUTZER

   IDX_BENUTZER : Integer (Autowert)
   B_NAME       : VarChar(30)
... und noch ein paar weitere Spalten, die ebenfalls nicht relevant sind ...
Da der Administrator seine Log-Tabelle auch sortieren können möchte, treten erhebliche Verzögerungen auf, wenn nach einem der Lookup-Felder sortiert werden muß. Als Lösung habe ich mir ein View in der Datenbank erstellt und siehe da: die Sortierung ist nun erheblich schneller bei den Lookup-Feldern. Doch ein Problem gibt es bei diesem View noch immer: Ich kann zwar die Spalte BENUTZER joinen, nicht jedoch zusätzlich noch die Spalte ZIELUSER:
Code:
CREATE OR ALTER VIEW V_LOGS(
    L_INDEX,
    L_BENUTZER,
    L_PASS,
    L_AKTION,
    L_ZEIT,
    L_ZIEL)
AS
select
    USER_LOG.IDX_USER_LOG,
    BENUTZER.B_NAME,
    BENUTZER.B_PASS,
    AKTIONEN.AKTION,
    USER_LOG.AKTIONZEIT,
    USER_LOG.ZIELUSER

from USER_LOG
inner join BENUTZER on BENUTZER.IDX_BENUTZER = USER_LOG.BENUTZER
inner join AKTIONEN on AKTIONEN.IDX_AKTIONEN = USER_LOG.AKTION
;
So funktioniert das View, doch wird natürlich der Zieluser nur als Index angezeigt. Wenn ich statt der letzten Zeile im Select-Abschnitt statt USER_LOG.ZIELUSER noch einmal BENUTZER.B_NAME schreibe, erhalte ich zwar keine Fehlermeldung vom Firebird-Server, doch wird nun in der Spalte L_ZIEL der Wert der Spalte L_BENUTZER eingetragen, was logisch ist. Um das zu vermeiden, habe ich im From-Sektor des Vies noch diese Zeile eingefügt:
Code:
...
AS
select
    USER_LOG.IDX_USER_LOG,
    BENUTZER.B_NAME,
    BENUTZER.B_PASS,
    AKTIONEN.AKTION,
    USER_LOG.AKTIONZEIT,
    BENUTZER.B_NAME

from USER_LOG
inner join BENUTZER on BENUTZER.IDX_BENUTZER = USER_LOG.BENUTZER
inner join BENUTZER on BENUTZER.IDX_BENUTZER = USER_LOG.ZIELUSER
inner join AKTIONEN on AKTIONEN.IDX_AKTIONEN = USER_LOG.AKTION
;
Das erzeugt diese Fehlermeldung:
Code:
Undefined name.
Dynamic SQL Error.
SQL error code = -204.
Ambiguous field name between table BENUTZER and table BENUTZER .
IDX_BENUTZER.
Nun meine Frage: Gibt es eine Möglichkeit, in der Spalte L_ZIEL den richtigen Benutzernamen anzuzeigen? Beim Sortieren nach dem Feld Zieluser tritt nämlich wieder die altbekannte Verzögerung auf, da ich im DBGrid hier natürlich wieder ein Lookup-Feld verwenden muß.

Lemmy 28. Jul 2013 17:22

AW: Firebird View inner join
 
Hi

Zitat:

Zitat von Perlsau (Beitrag 1222870)
Code:
...
AS
select
    USER_LOG.IDX_USER_LOG,
    A.B_NAME,
    A.B_PASS,
    AKTIONEN.AKTION,
    USER_LOG.AKTIONZEIT,
    B.B_NAME

from USER_LOG
inner join BENUTZER A on A.IDX_BENUTZER = USER_LOG.BENUTZER
inner join BENUTZER B on B.IDX_BENUTZER = USER_LOG.ZIELUSER
inner join AKTIONEN on AKTIONEN.IDX_AKTIONEN = USER_LOG.AKTION
;

du musst die beiden joins voneinander klar trennen, das machst Du einfach mit einem Alias.

Perlsau 28. Jul 2013 17:33

AW: Firebird View inner join
 
Guten Abend Lemmy,

das steht in meinem SQL-Einsteigerhandbuch leider nicht drin, funktioniert aber auf Anhieb. Herzlichen Dank dafür :thumb:

... obwohl da ja schon irgendwas mit Aliassen steht, das muß ich gleich mal durcharbeiten ...:gruebel:

p80286 28. Jul 2013 21:52

AW: Firebird View inner join
 
Ich denke, das ist ein Mißverständnis.
Der Alias ist nichts anderes als ein anderer Name.
In diesem Fall wird der Alias genutzt um eine Tabelle zweimal zur Verfügung zu stellen. Wenn man so mag Du hast zwei Benutzertabellen (A und B)

Gruß
K-H

Furtbichler 29. Jul 2013 07:33

AW: Firebird View inner join
 
Ich finde, Du solltest die Begriffe 'Index', 'Primary Key' und 'Foreign Key' mal nachschlagen.

Ein 'Index' ist ein Hilfsmittel, um in einer Tabelle schnell bestimmte Werte einer Spalte finden zu können. Ohne Index geht's auch, aber mit ist eben viel viel schneller (Wie ein Index in einem Buch, um ein Schlagwort zu finden).

Ein 'Primary Key' ist eine Spalte mit einem für diese Tabelle eindeutigen Wert, anhand dessen die Zeile (der Datensatz) eindeutig identifiziert werden kann. Es gibt auch primary keys, die aus mehreren Spalten bestehen, aber vergiss das einfach.
Dein 'IDX_USER_LOG' ist der Primary Key der Tabelle 'User_Log'.

Natürlich ist es zweckmäßig, für einen Primary Key einen Index zu definieren, damit man den einzelnen Datensatz anhand seiner ID schnell finden kann. Zwingend ist das zwar nicht, aber da man ein offizieller Vollpfosten ist, wenn man das nicht macht, erstellen eigentlich alle RDBMS so einen Index für dich mit, wenn Du eine Spalte als primary key deklarierst.

Ein 'Foreign Key' ist nichts anderes als die Referenz auf einen primary key, aber in einer anderen Tabelle.
Die Spalte 'BENUTZER' ist ein foreign key in der Tabelle UserLog auf die Tabelle User.

Perlsau 29. Jul 2013 07:37

AW: Firebird View inner join
 
Zitat:

Zitat von Furtbichler (Beitrag 1222893)
Ich finde, Du solltest die Begriffe 'Index', 'Primary Key' und 'Foreign Key' mal nachschlagen.

Ist ja sicher nett gemeint, aber glaubst du im Ernst, ich wüßte nach mehreren Jahren der Datenbankprogrammierung nicht, was diese Begriffe bedeuten? Wie kommst du eigentlich darauf?

mkinzler 29. Jul 2013 07:48

AW: Firebird View inner join
 
Zitat:

Zitat von Perlsau (Beitrag 1222895)
Zitat:

Zitat von Furtbichler (Beitrag 1222893)
Ich finde, Du solltest die Begriffe 'Index', 'Primary Key' und 'Foreign Key' mal nachschlagen.

Ist ja sicher nett gemeint, aber glaubst du im Ernst, ich wüßte nach mehreren Jahren der Datenbankprogrammierung nicht, was diese Begriffe bedeuten? Wie kommst du eigentlich darauf?

Anhand Deiner Formulierung in Deiner Ausgangsfrage:
Zitat:

In dieser Tabelle gibt es einmal eine Spalte Benutzer, die einen Index auf den Benutzernamen (IDX_BENUTZER) der Tabelle BENUTZER enthält
Zwar wird für jedes Schlüsselfeld auch ein Index angelegt, aber in diesem Fall wäre die Formulierung:
In dieser Tabelle gibt es einmal eine Spalte Benutzer, welche eine Fremdschlüssel auf die Tabelle BENUTZER ist.[/QUOTE] besser gewesen.

Perlsau 29. Jul 2013 07:54

AW: Firebird View inner join
 
Zitat:

Zitat von mkinzler (Beitrag 1222896)
Zwar wird für jedes Schlüsselfeld auch ein Index angelegt, aber in diesem Fall wäre die Formulierung:
Zitat:

In dieser Tabelle gibt es einmal eine Spalte Benutzer, welche eine Fremdschlüssel auf die Tabelle BENUTZER ist.
besser gewesen.

Das leuchtet ein :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:14 Uhr.

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