Как получить текст для языка по умолчанию
-
16-10-2019 - |
Вопрос
У меня таблицы:
И так данные в языковой таблице:
И так данные в текстовой таблице:
Я должен вернуть текст для запрошен Язык, если это существуют и текст для дефолт Язык, если это так не существует. Анкет Возможно ли сделать это в один запрос (нет while
, пожалуйста)?
Код:
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
Спасибо.
ДОБАВЛЕН:
Если код запрашивает текст в «ua» (украинский), и это не является текстом для этого языка, так что он будет искать текст для русских. Если найдено - ОК, если не будет искать текст для английского. Список языков может варьироваться.
Решение
Используя рекурсивный CTE, этот запрос создает таблицу всех языков, которые указывают где -то в их цепочке по умолчанию на язык, который имеет необходимый комментарий. Он показывает каждый язык рядом с первым дефолтом, который имеет необходимый комментарий. Затем он фильтрует эту таблицу, чтобы дать вам первый доступный текст для выбранного вами языка.
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
;
Попробуйте просто бежать
SELECT *
FROM languages;
Если вы хотите почувствовать, что делает рекурсивный CTE. Я загрузил скрипт для создания таблиц, вставьте некоторые образцы данных и запустил приведенный выше код Гист.
Довольно сексуально, нет?