Schrift
[thread]1012[/thread]

SQL - Sprachauswahl WHERE-Klausel mit "Fallback"?: Geht sowas?



<< >> 6 Einträge, 1 Seite
renee
 2006-01-31 00:08
#10354 #10354
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn mich meine Datenbankkenntnisse noch nicht vollständig verlassen haben, suchst Du nach einem OUTER JOIN... (siehe: http://www.aspheute.com/artikel/20001023.htm und http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/chap7.htm#leftjoin )
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pq
 2006-01-31 09:35
#10355 #10355
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
für übersetzungen lohnt es sich, mal gettext auszuprobieren.
die strategie finde ich auch zu wirr. "wenn keine übersetzung vorhanden, nimm
die, die zuerst eingegeben wurde" - das muss ja nicht immer dieselbe sprache sein.
wenn dann würde ich schon immer den gleichen fallback haben wollen.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Cremator
 2006-01-31 20:34
#10356 #10356
User since
2003-11-26
97 Artikel
BenutzerIn
[default_avatar]
Ja, pq hat natuerlich recht mit der Aussage das "die strategie zu wirr" ist.

Ich hab's jetzt so geloest das ich in die Tabelle mit den Sprachen eine Preferenz-Spalte eingefuegt habe. Dann lese ich einfach alle Records aus der translations-tabelle die es zu einer ID gibt (inkl. lang_code) und vergleiche ob die Sprachpreferenz des aktuellen Records groesser ist als der vorherige.

So kann der Benutzer auch einstellen in welcher Gewichtung die Sprachen ausgewählt werden.
Cremator
 2006-01-30 20:09
#10357 #10357
User since
2003-11-26
97 Artikel
BenutzerIn
[default_avatar]
Benutze Datenbank ist MySQL 4.1 mit Standard MyISAM Tabellen.

Ich habe hier eine Tabelle für Übersetzungen:
Code: (dl )
1
2
3
4
5
6
7
8
CREATE TABLE translations (
id BIGINT NOT NULL AUTO_INCREMENT,
lang_code CHAR(5) NOT NULL,
item_id BIGINT NOT NULL,
item_name VARCHAR(255) NOT NULL,
item_desciption TEXT NULL,
PRIMARY KEY(id)
);

item_id ist der Foreign Key der das gesuchte Element referenziert (zur id aus der Tabelle items).

Jetzt will ich aus dieser Tabelle alle übersetzten item_name und item_description für eine bestimmte Sprache und einen bestimmten level (der ist in der Tabelle items definiert) abfragen. Das sieht bisher so aus:
Code: (dl )
1
2
3
4
5
6
SELECT i.id, i.level, t.item_name, t.item_desciption
FROM items i, translations t
WHERE t.lang_code = 'en_US'
AND i.id = t.item_id
AND i.level = 3
ORDER BY t.name;

Alles prima solange alle Elemente übersetzt sind. Wenn nicht fehlt's eben und das ist nicht gut.

Andere Alternative wäre die Sprachklausel rauszuwerfen und nach Item-ID zu gruppieren:
Code: (dl )
1
2
3
4
5
6
SELECT i.id, i.level, t.item_name, t.item_desciption
FROM items i, translations t
WHERE i.id = t.item_id
AND i.level = 3
GROUP BY i.id
ORDER BY t.name;

Dann hab ich zwar immer einen String den ich anzeigen kann, aber dafür völliges Sprachkauderwelsch. Die zuerst in die Tabelle eingetragene Übersetzung für ein Item wird zurückgegeben.

Jetzt würde ich die beiden Varianten gerne kombinieren:
Wenn eine Übersetzung für die vorgegebene Sprache vorhanden ist soll die zurückgegeben werden, sonst eben die zuerst eingetragene.

Und ich steh' mit beiden Füssen auf'm Schlauch...

Edit: DB-Typ nachgetragen\n\n

<!--EDIT|Cremator|1138645368-->
murphy
 2006-01-31 03:22
#10358 #10358
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Naja, also mit relationalen Joins alleine kommt man da, glaube ich, noch nicht zum gewünschten Ergebnis. Das einzige was mit als Lösungsansatz einfällt sind verschachtelte SELECTs. Ich gebe mal ein Beispiel, das ich mit SQLite ausprobiert habe. Testdaten:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh
sqlite3 blubb.db <<EOD
CREATE TABLE items(id INTEGER, level INTEGER, PRIMARY KEY(id));
INSERT INTO items VALUES(1, 1);
INSERT INTO items VALUES(2, 1);
INSERT INTO items VALUES(3, 2);
INSERT INTO items VALUES(4, 3);
INSERT INTO items VALUES(5, 3);
INSERT INTO items VALUES(6, 3);

CREATE TABLE translations(id INTEGER, lang TEXT, name TEXT, UNIQUE(id, lang));
INSERT INTO translations VALUES(1, 'en', 'buy');
INSERT INTO translations VALUES(1, 'de', 'kaufen');
INSERT INTO translations VALUES(1, 'is', 'kaupa');
INSERT INTO translations VALUES(1, 'fr', 'acheter');
INSERT INTO translations VALUES(2, 'en', 'sell');
INSERT INTO translations VALUES(2, 'is', 'selja');
INSERT INTO translations VALUES(3, 'is', 'laera');
INSERT INTO translations VALUES(3, 'fr', 'apprendre');
INSERT INTO translations VALUES(4, 'de', 'trinken');
INSERT INTO translations VALUES(4, 'en', 'drink');
INSERT INTO translations VALUES(4, 'is', 'drekka');
INSERT INTO translations VALUES(5, 'en', 'quit');
INSERT INTO translations VALUES(6, 'fr', 'annuler');
EOD


Und jetzt die Abfrage:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/perl -T
use strict;
use warnings;

use DBI;

my $db = DBI->connect('dbi:SQLite:dbname=blubb.db',
'', '',
{ RaiseError => 1 });


my $stmt = $db->prepare(<<'EOD');
SELECT
(CASE
WHEN t.lang ISNULL THEN
(SELECT name FROM translations WHERE id = i.id)
ELSE
t.name
END) AS name
FROM
items AS i LEFT OUTER JOIN translations AS t
ON
i.id = t.id AND t.lang = ?
WHERE i.id = ? AND i.level = ?;
EOD

sub x {
printf "lang = %s, id = %d, level = %d ==> ", @_;
$stmt->execute(@_);
print $stmt->fetchrow_array();
print "\n";
}

x('is', 2, 1);
x('de', 2, 1);

$stmt->finish();
$db->disconnect();


Funktioniert, ist aber nicht gerade schön und vermutlich auch nicht wahnsinnig schnell, wenn man viele Datensätze hat.
When C++ is your hammer, every problem looks like your thumb.
murphy
 2006-01-31 15:48
#10359 #10359
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
gettext ist natürlich eine solide und gute Lösung, wenn man ein Programm in verschiedene Sprachen übersetzen möchte. Aber es mag schon Gründe geben, warum die Lokalisierungsdaten in einer Datenbank besser aufgehoben sein könnten -- zum Beispiel wenn sich die Menge der Dinge, die verschiedensprachig beschrieben werden müssen, zur Laufzeit ständig änderte.

Eine Standardsprache für den Notfall zu definieren halte ich aber auch für schlau. Das wäre auch einfacher in SQL realisierbar.
When C++ is your hammer, every problem looks like your thumb.
<< >> 6 Einträge, 1 Seite



View all threads created 2006-01-31 00:08.