AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null
Thema durchsuchen
Ansicht
Themen-Optionen

Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null

Ein Thema von raller09 · begonnen am 10. Apr 2013 · letzter Beitrag vom 11. Apr 2013
Antwort Antwort
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null

  Alt 10. Apr 2013, 14:47
Datenbank: Interbase • Version: XE • Zugriff über: isql
Hi,

brauche mal eure Hilfe:

Ich möchte für Ausdrucke und an vielen Stellen im Programm für die Anzeige folgende Funktion umsetzen:
Wenn bei der übergebenen Sprache keine Daten (kein DS oder Feld-Wert ist null oder Leer-String) vorhanden sind, dann Lese die Daten aus der Standard-Sprache (im Beispiel 1) nach.
Da der Zugriff über viele Stellen im SourceCode erfolgt, wollte ich die Rückgabe des Übersetzten Text über die Datenbank lösen. Hierdurch müssten nich alle Stellen im Programm geändert werden.


Folgende Struktur (Beispiel) ist gegeben:
Code:
Tabelle BRANCHEN
ID               Integer (PKey)
(je nach Tabelle weitere Daten-Felder)

Tabelle SPRACHEN
SPRACHID         Integer (PKey)

Tabelle SPRACHEN_SPRACHE
SPRACHID         Integer (PKey)
BEZEICHNUNG      VarChar(100)

Tabelle BRANCHEN_SPRACHE
ID               Integer (PKey)
SPRACHID         Integer (PKey)
BEZEICHNUNG      VarChar(100)
MEMOTEXT         BLOB SUB_TYPE TEXT
Daten:
Code:
Branchen:      Sprachen:      Sprachen_Sprache:
ID             ID             ID | SPRACHID | BEZEICHNUNG
-----------     -----------     -----------------------------------------
 1               1               1 |        2 | Englisch
 2               2               2 |        2 | Deutsch
 3               3               3 |        2 | Französisch

Branchen_Sprache:
ID | SPRACHID | Bezeichnung                              | MemoText
--------------------------------------------------------------------------------
 1 |        1 | Computer programming activities          | aaaaaaaaaaa
 1 |        2 | Programmierungstätigkeiten               | 
 1 |        3 | (null)                                   | (null)
 2 |        1 | Computer consultancy activities          | (null)
 3 |        1 | Computer facilities management activities | (null)
Die Standard-Sprache (1. Englisch) ist in der Datenbank über einen
Generator "Standard_SprachID"
festgelegt.


Aktuelle Abfragen sind folgendermaßen aufgebaut:

SQL-Code:
Select bs.BEZEICHNUNG
from BRANCHEN b
left outer join BRANCHEN_SPRACHE bs on b.ID = bs.ID and b.SPRACHID = 3;
Diese liefern für die ausgewählte Sprache den entsprechenden Text;


Ich habe mir zuerst eine "stored procedure" geschrieben, die den Tabellen-Name, Feld-Namen und die Sprache übergeben bekommt und dafür den entsprechenden Text zurückgibt.
Aber auch mit dieser müsste ich den gesammten SourceCode überarbeiten.


Danach wollte ich das mittels "computed by" Feldern in der jeweiligen Sprach-Tabelle umsetzen:

Das scheitert aber an (bis jetzt) 2 Problemen:

1. Interbase kommt mit einem "case when" in der "computed by" Bedingung nicht zurecht, siehe QN: 110482
2. Ich hab es nur für Firebird gefunden, das BLOB-Felder in "computed by" nicht erlaubt sind. Bin nicht Sicher wie es für Interbase ist.


Daher hab ich mir eine "View" erstellt:
SQL-Code:
create view BRANCHEN_SPRACHE_MITDEF ( ID,
                                      SPRACHID,
                                      BEZEICHNUNG,
                                      MEMOTEXT) as
Select rss.ID,
       rss.SPRACHID,
       coalesce( NullIf( rss.BEZEICHNUNG , ''), sbs.BEZEICHNUNG),
       coalesce( case RTrim( cast( rss.MEMOTEXT as varchar(10))) when 'then null else bs.MEMOTEXT end, sbs.MEMOTEXT)
from BRANCHEN_SPRACHE bs
left outer join BRANCHEN_SPRACHE sbs on sbs.ID = bs.ID and sbs.SPRACHID = gen_ID( Standard_SprachID, 0);
Diese liefert mir schon fast das richtige Ergebnis.

Ein Problem ist aber noch vorhanden:
Wenn Daten für eine Sprache abgefragt werden, für die in der Sprach-Tabelle noch gar kein Eintrag vorhanden ist, dann wird bei einem join nich die Standard-Sprache ausgegeben.
Der Aufruf von
SQL-Code:
Select b.ID, bsmd.BEZEICHNUNG, bsmd.MEMOTEXT
from BRANCHEN b
left outer join BRANCHEN_SPRACHE_MITDEF bsmd on bsmd.ID = b.ID and bsmd.SPRACHID = 3
where b.ID = :ID;
liefert für
ID = 1 -> englische Bezeichnung (wie gewünscht)
ID = 2 -> (null) für die Bezeichnungen (das ist nicht so gewünscht)
Wenn ich ein
Insert into BRANCHEN_SPRACHE (ID, SPRACHID) (2, 3); mache, liefert der oben angeführte Sql-Befehl die Bezeichnung der Standard-Sprache.

Wie kann ich auch ohne den Insert die Daten der Standard-Sprache zurückgeben?

Geändert von raller09 (10. Apr 2013 um 17:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null

  Alt 10. Apr 2013, 15:21
Wenn ich mir so ansehe, wie du COALESCE verwendest

COALESCE( NullIf( rss.BEZEICHNUNG , ''), sbs.BEZEICHNUNG) dann befürchte ich, dass du nicht verstanden hast, was der macht

SQL-Code:
COALESCE( 'Hallo', 'Du', 'Da' ) => 'Hallo';
COALESCE( NULL, 'Du', 'Da' ) => 'Du';
COALESCE( NULL, NULL, 'Da' ) => 'Da';
COALESCE( NULL, NULL, NULL ) => NULL
Die Abfrage könnte dann so aussehen (SprachID 1 ist default und komplett)
SQL-Code:
         SELECT b.ID AS ID,
                COALESCE( bs.Bezeichnung, bsd.Bezeichnung ) AS Bezeichnung,
                COALESCE( bs.MemoText, bsd.MemoText ) AS MemoText
           FROM Branchen b
           JOIN Branchen_Sprache bsd ON b.ID = bsd.ID AND bsd.SprachID = 1
LEFT OUTER JOIN Branchen_Sprache bs ON b.ID = bs.ID AND bs.SprachID = 3
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (10. Apr 2013 um 15:31 Uhr)
  Mit Zitat antworten Zitat
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null

  Alt 10. Apr 2013, 16:03
Wenn ich mir so ansehe, wie du COALESCE verwendest

COALESCE( NullIf( rss.BEZEICHNUNG , ''), sbs.BEZEICHNUNG) dann befürchte ich, dass du nicht verstanden hast, was der macht
möglich. aber er macht genau dass, was ich will.


SQL-Code:
COALESCE( 'Hallo'             , 'Du') => 'Hallo';
COALESCE( ''                  , 'Du') => ''; <- Das soll so nicht
COALESCE( NULL , 'Du') => 'Du';

COALESCE( NullIf( 'Hallo', ''), 'Du') => 'Hallo';
COALESCE( NullIf( ''     , ''), 'Du') => 'Du'; <- durch NullIf wird 'Du' zurückgegeben
COALESCE( NullIf( NULL , ''), 'Du') => 'Du';
Ich habe bei meiner Verwendung keinen Fehler festgestellt. Läuft da was Falsch?


Die Abfrage könnte dann so aussehen (SprachID 1 ist default und komplett)
SQL-Code:
         SELECT b.ID AS ID,
                COALESCE( bs.Bezeichnung, bsd.Bezeichnung ) AS Bezeichnung,
                COALESCE( bs.MemoText, bsd.MemoText ) AS MemoText
           FROM Branchen b
           JOIN Branchen_Sprache bsd ON b.ID = bsd.ID AND bsd.SprachID = 1
LEFT OUTER JOIN Branchen_Sprache bs ON b.ID = bs.ID AND bs.SprachID = 3
Stimmt. Gute Idee.
Leider kann ich gerade nicht überblicken, ob die Standard-Sprache immer komplett gefüllt ist...

Geht dass auch ohne diese Annahme?


Danke,

Ralf
  Mit Zitat antworten Zitat
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Rückgabe eines Wertes aus anderer Zeile, wenn aktueller Wert = null

  Alt 11. Apr 2013, 17:21
Hi,

gerade noch mal nachgedacht:

Stimmt. Gute Idee.
Leider kann ich gerade nicht überblicken, ob die Standard-Sprache immer komplett gefüllt ist...

Geht dass auch ohne diese Annahme?
macht keinen Sinn. Wenn Standard + aktuelle Sprache nicht da, dann natürlich auch keine Übersetzung.


Die Abfrage könnte dann so aussehen (SprachID 1 ist default und komplett)
SQL-Code:
         SELECT b.ID AS ID,
                COALESCE( bs.Bezeichnung, bsd.Bezeichnung ) AS Bezeichnung,
                COALESCE( bs.MemoText, bsd.MemoText ) AS MemoText
           FROM Branchen b
           JOIN Branchen_Sprache bsd ON b.ID = bsd.ID AND bsd.SprachID = 1
LEFT OUTER JOIN Branchen_Sprache bs ON b.ID = bs.ID AND bs.SprachID = 3
Das ist aber ja die Schreibweise ohne View oder ähnliches... dafür müssen alle Stellen im Programm individuell angepasst werden. Das will ich eigendlich vermeiden.



MfG

Ralf
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:59 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