Come arrivare il testo per la lingua di default
-
16-10-2019 - |
Domanda
Ho così le tabelle:
e così i dati in tabella Lingua:
e così i dati al tavolo di testo:
devo tornare di testo per richiesta ??em> lingua, se esiste e il testo per default lingua, se lo fa non esiste . E 'possibile farlo in una query (senza while
, per favore)?
Codice:
DECLARE @CommentId bigint = 1
--DECLARE @LanguageCode nvarchar(2) = 'en' -- "english text" returns
DECLARE @LanguageCode nvarchar(2) = 'ua' -- nothing at this moment
SELECT
t.CommentId
,t.TextId
,t.[Text]
,t.LanguageId
,RequestedLanguageId = @LanguageCode
FROM dbo.common_Text t
INNER JOIN dbo.common_LanguageType l
ON t.LanguageId = l.LanguageId
WHERE l.Code = @LanguageCode
AND t.CommentId = @CommentId
Grazie.
AGGIUNTO:
Se il codice richiede un testo in 'ua' (ucraino) e questo non è un qualsiasi testo per questa lingua, in modo da sta andando a cercare il testo per il russo. se trovato - ok, se non cercherà un testo per l'inglese. Elenco delle lingue può variare.
Soluzione
Utilizzando un CTE ricorsiva, questa query costruisce una tabella di tutte le lingue quel punto da qualche parte nella loro catena di default ad una lingua che ha il commento desiderato. Essa mostra ogni lingua vicino alla sua prima di default che ha il commento desiderato. E poi filtra questa tabella di darvi il primo testo disponibile per la lingua selezionata.
DECLARE @CommentId BIGINT = 1;
DECLARE @LanguageCode NVARCHAR(2) = 'en';
WITH languages AS (
-- base case: language has required comment
SELECT
lt.LanguageId AS RootLanguageId
, lt.LanguageId
, lt.Code
, lt.DefaultId
, 0 AS Level
FROM
dbo.common_LanguageType lt
--WHERE
-- lt.LanguageId = lt.DefaultId
WHERE
EXISTS (
SELECT *
FROM dbo.common_Text t
WHERE
t.CommentId = @CommentId
AND t.LanguageId = lt.LanguageId
)
UNION ALL
-- recursive case: language is not its own default and
-- does not have the required comment
SELECT
l_default.RootLanguageId
, l.LanguageId
, l.Code
, l.DefaultId
, l_default.Level + 1 AS Level
FROM
dbo.common_LanguageType l
INNER JOIN languages l_default
ON l.DefaultId = l_default.LanguageId
WHERE
l.LanguageId <> l.DefaultId
AND NOT EXISTS (
SELECT *
FROM dbo.common_Text t
WHERE
t.CommentId = @CommentId
AND t.LanguageId = l.LanguageId
)
)
SELECT t.Text
FROM
languages l
INNER JOIN dbo.common_Text t
ON l.RootLanguageId = t.LanguageId
WHERE
l.Code = @LanguageCode
;
Prova solo in esecuzione
SELECT *
FROM languages;
se si vuole avere un'idea di ciò che il CTE ricorsiva sta facendo. Ho caricato uno script per creare le tabelle, inserire alcuni dati di esempio, ed eseguire il codice di cui sopra a Gist .
abbastanza sexy, no?