Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Поддержка multi language на уровне хранимок  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
Приветствую всех.

Решил сделать поддержку multi language для ответов возвращаемых через хранимку.
Например, раньше при определенном ответе, просто возвращал ответ: "Нет доступа к документу <Оплаты>", то теперь нужно
такой же ответ возвращать в зависимости от языка сессии или пользователя, это уже не важно.
Например:
русский: Нет доступа к документу "Оплаты"
английский: No access to the document "Payments"

Пока думаю над таким вариантом:
declare
	@MultiLanguageText table (
		Language varchar(10),
		Action varchar(50),
		Text xml
	)

declare
	@ParamsList TABLE (
		Name varchar(20),
		Value nvarchar(200)
	)

insert into @MultiLanguageText select 'ru-RU', 'NewPayment', '<text><params><param name="PaySum" /></params><t>Оплата в размере %PaySum%$ зарегистрирована</t></text>'
insert into @MultiLanguageText select 'en-EN', 'NewPayment', '<text><params><param name="PaySum" /></params><t>Payment of %PaySum%$ is registered</t></text>'
insert into @MultiLanguageText select 'ru-RU', 'BalanceAlert', '<text><params><param name="Balance" /><param name="Now" /></params><t>Ваш баланс меньше допустимого предела! Баланс: %Balance%$. %Now%</t></text>'
insert into @MultiLanguageText select 'en-EN', 'BalanceAlert', '<text><params><param name="Balance" /><param name="Now" /></params><t>Your balance is less than limit! Balance: %Balance$. %Now%</t></text>'

declare
	@Language varchar(10),
	@Action nvarchar(50),
	@OutputText nvarchar(MAX),
	@Text xml,
	@Params xml


--New payment
set @Language='ru-RU'
set @Action='NewPayment'
set @Params='<params><param name="PaySum">100</param></params>'

select @OutputText=Text.value('(/text/t)[1]','nvarchar(500)') from @MultiLanguageText where Language=@Language and Action=@Action
insert into @ParamsList select Tbl.Col.value('@name','varchar(20)'), Tbl.Col.value('.','nvarchar(200)') from @Params.nodes('/params/param')Tbl(Col)
select @OutputText=replace(@OutputText,('%'+Name+'%'),Value) from @ParamsList

print @OutputText

--Balance alert
set @Language='ru-RU'
set @Action='BalanceAlert'
set @Params='<params><param name="Balance">-2000</param><param name="Now">11:00</param></params>'

select @OutputText=Text.value('(/text/t)[1]','nvarchar(500)') from @MultiLanguageText where Language=@Language and Action=@Action
insert into @ParamsList select Tbl.Col.value('@name','varchar(20)'), Tbl.Col.value('.','nvarchar(200)') from @Params.nodes('/params/param')Tbl(Col)
select @OutputText=replace(@OutputText,('%'+Name+'%'),Value) from @ParamsList

print @OutputText


Но может быть есть более элегантное решение?

Спасибо.
15 июл 15, 09:28    [17893600]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
Glory
Member

Откуда:
Сообщений: 104751
orunbek
Но может быть есть более элегантное решение?

А зачем в @MultiLanguageText заносить текст сообщения в xml ?
15 июл 15, 09:54    [17893697]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
o-o
Guest
а в чем проблема с языками-то?
организуете таблицу со всеми своими сообщениями,
в каждой строке кроме номера сообщения и текста еще и id языка,
ну и фильтруйте по нему при выводе.
как в sys.messages-то сделано?
правда, у них language_id это не тот что @@LANGID,
но никто вам не мешает занести в вашу таблицу именно @@LANGID
--create proc dbo.sp_lang 
 --@msg_id int
 --as
 --   select text
 --   from sys.messages
 --   where message_id = @msg_id
 --         and language_id = case @@LANGID
 --                                when 6 then 1040
 --                                when 21 then 1049
 --                                when 0 then 1033
 --                                else 2052
 --                           end;    

set language 'us_english';
exec dbo.sp_lang 802;

set language 'russian';
exec dbo.sp_lang 802;

set language 'italian';
exec dbo.sp_lang 802;


К сообщению приложен файл. Размер - 58Kb
15 июл 15, 12:01    [17894327]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
Если бы нужно было генерировать статичный текст, завел бы таблицу с идентификатором языка и текста и все.
А здесь текст должен содержать дополнительную информацию, и конечный текст будет меняться из этого содержимого.
15 июл 15, 13:24    [17894800]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
o-o
Guest
orunbek,

у MS так и сделано, вместо %d, %S_DATE подставляется та самая конкретная информация:
Warning: Fatal error %d occurred at %S_DATE. Note the error and time, and contact your system administrator.

или вы "на ходу" еще и переводить собираетесь?
15 июл 15, 13:30    [17894828]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
orunbek, вы бы хоть заглянули в sys.messages, как вам порекомендовали.

в строке там вместо дополнительного текста, который может меняться от раза к разу, ставится "%s", "%1", "%2", или другой символ для обозначения места для подстановки, а при выдаче конкретного сообщения он заменяется на нужный дополнительный текст.
15 июл 15, 13:33    [17894844]     Ответить | Цитировать Сообщить модератору
 Re: Поддержка multi language на уровне хранимок  [new]
orunbek
Member

Откуда: Гималай
Сообщений: 2101
Спасибо за советы, посмотрел sys.messages, "велосипед уже изобрели оказывается" :)

Я чуток видоизменил, и все равно решил Xml тоже добавить, для облегчения поддержки Multi-language ответов
declare
	@Messages table (
		ID int primary key,
		Message varchar(50),
		Params xml
	)
declare
	@Text table (
		Language_ID smallint,
		Message_ID int,
		Text nvarchar(MAX)
	)


declare
	@ParamsList TABLE (
		Name varchar(20),
		Value nvarchar(200)
	)

insert into @Messages (ID, Message, Params) select 1, 'NewPayment', '<params><param name="PaySum" description="Сумма оплаты" /></params>'
insert into @Messages (ID, Message, Params) select 2, 'BalanceAlert', '<params><param name="Balance" description="Баланс" /><param name="Now" description="Текущее время" /></params>'

insert into @Text select 1049, 1, N'Оплата в размере %PaySum$ зарегистрирована'
insert into @Text select 1033, 1, N'Payment of %PaySum$ is registered'
insert into @Text select 1049, 2, N'Ваш баланс меньше допустимого предела! Баланс: %Balance$. %Now'
insert into @Text select 1033, 2, N'Your balance is less than limit! Balance: %Balance$. %Now'

declare
	@Language_ID smallint,
	@Message nvarchar(50),
	@OutputText nvarchar(MAX),
	@Params xml
	
--New payment for 1049
set @Language_ID=1049
set @Message='NewPayment'
set @Params='<params><param name="PaySum">100</param></params>'
insert into @ParamsList select Tbl.Col.value('@name','varchar(20)'), Tbl.Col.value('.','nvarchar(200)') from @Params.nodes('/params/param')Tbl(Col)

select @OutputText=Text from @Text t inner join @Messages m on t.Message_ID=m.ID where t.Language_ID=@Language_ID and m.Message=@Message
select @OutputText=replace(@OutputText,('%'+Name),Value) from @ParamsList

print @OutputText

--New payment for 1033
set @Language_ID=1033
select @OutputText=Text from @Text t inner join @Messages m on t.Message_ID=m.ID where t.Language_ID=@Language_ID and m.Message=@Message
select @OutputText=replace(@OutputText,('%'+Name),Value) from @ParamsList

print @OutputText
print ''

--Balance alert for 1049
set @Language_ID=1049
set @Message='BalanceAlert'
set @Params='<params><param name="Balance">-1000</param><param name="Now">17:00</param></params>'
insert into @ParamsList select Tbl.Col.value('@name','varchar(20)'), Tbl.Col.value('.','nvarchar(200)') from @Params.nodes('/params/param')Tbl(Col)

select @OutputText=Text from @Text t inner join @Messages m on t.Message_ID=m.ID where t.Language_ID=@Language_ID and m.Message=@Message
select @OutputText=replace(@OutputText,('%'+Name),Value) from @ParamsList

print @OutputText

--Balance alert for 1033
set @Language_ID=1033
select @OutputText=Text from @Text t inner join @Messages m on t.Message_ID=m.ID where t.Language_ID=@Language_ID and m.Message=@Message
select @OutputText=replace(@OutputText,('%'+Name),Value) from @ParamsList

print @OutputText


Т.е. при необходимости могут через парсинг @Messages добавить ответы и для других языков.
В данном примере
1049 russian
1033 english
15 июл 15, 18:53    [17896578]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить