【问题标题】:Database Localization - Lookup lists - smarter way数据库本地化 - 查找列表 - 更智能的方式
【发布时间】:2012-01-25 01:15:06
【问题描述】:

我希望在数据库中添加一些查找列表,但我希望它们易于本地化(SQL 2005,ADO.NET)

这将包括:

  • 同时轻松管理多种语言
  • 从数据库中轻松检索值
  • 后备语言(以防所选语言丢失)

我正在考虑使用一个表来存储多语言查找列表(对不同语言使用相同的 ID)并使用一个函数来返回查找列表的值 - 通过接收 ID 和语言。

其中一个陷阱是我必须手动向使用查找列表的每个查询添加语言参数。

我正在寻找一种解决方案,可以让我将参数作为“会话/全局变量”发送,或者使用 sql 查询自动发送参数,以及自行检索它的函数(或者附加参数自动,要么能够读取参数)。

解决方案可能看起来像这样,但我不介意它是否不同,只要它没有将参数显式地提供给查询(伪代码):

1. Send the language using "the method"
2. Execute Query
3. Get the localized results

澄清:

  1. 通常查询看起来像这样(记住使用查找功能):

    SELECT .., GetLookupList1(lookup_ID, language), .. FROM TABLE

GetLookupList1 是一个用户定义的函数,用于检索查找表的查找值。通过使用该功能,SQL 代码更易于阅读和维护。

函数的主体类似于:

SELECT @result = LookupValue FROM LookupTable1 WHERE ID=@Lookup_ID and Language=@lang
RETURN @result
  1. 我想要的是能够将语言参数从函数中删除为某种静态变量,仅适用于当前连接/语句/命令,因此查询看起来像

    SELECT .., GetLookupList1(lookup_ID), .. FROM TABLE

【问题讨论】:

    标签: .net database tsql ado.net


    【解决方案1】:

    如果您像这样构建数据:

    MessageToken    DisplayText       LangCode
    firewood        Fire wood         en
    firewood        Bois de chauffage fr
    

    当您进行查询时,只需提供默认语言 ID(如果为空)或提供的语言 ID。对消息使用标准的令牌列表。

    Select DisplayText from (some table) where MessageToken = 'firewood' and LangId = 'en'
    

    【讨论】:

      【解决方案2】:

      由于 SQL Server 中没有用户定义的全局变量,因此您必须使用以下两种方法之一:

      1. 表 - 临时或永久。永久表示例:http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx
      2. 设置上下文信息:http://msdn.microsoft.com/en-us/library/ms187768.aspx。 Context_info 允许您将 128 个二进制字节与会话/连接相关联。它有效,但要小心。如果您养成使用它的习惯,您可能会在另一个上下文中意外覆盖它。每个会话/连接只有一个。

      示例 context_info t-sql:

      declare @languagein varchar(30), @contextin varbinary(128),
          @languageout varchar(30), @contextout varbinary(128)
      
      select @languagein = 'ro-RO'
      select @contextin = cast(@languagein as varbinary(128))
      set context_info @contextin
      
      --do whatever you like here: queries, stored procs. 
      --context_info stays 'ro-RO' for the duration of the session/connection
      
      select @contextout = context_info()
      set @languageout = replace(cast(@contextout as varchar(30)),0x00, '')
      print @languageout
      

      我在本地化中使用的另一种技术是三部分合并以确保结果。首先检查语言区域,然后是语言,然后是默认值。根据您的查询:

      SELECT COALESCE(langregion.LookupValue, lang.LookupValue, fallback.LookupValue) LookupVal
      FROM LookupTable1 fallback
      LEFT OUTER JOIN LookupTable1 lang 
          ON lang.ID = fallback.ID AND lang.Lang = @language
      LEFT OUTER JOIN LookupTable1 langregion 
          ON langregion.ID = fallback.ID AND langregion.Lang = @languagewithregion
      WHERE fallback.ID = @Lookup_ID
      AND fallback.Lang = @defaultlanguage
      

      【讨论】:

      • 但是如果使用上下文信息,例如使用连接池,命令可以在不同的连接上运行.. 与 SET LANGUAGE 相同
      • 如果在每个Command开头设置context_info应该没问题。当连接处于活动状态时,没有其他命令可以在该连接上运行。您的连接仅在命令期间变得特定于语言,而不是在会话/连接的生命周期内。
      • 我认为 Context_INFO 与 SET LANGUAGE 具有相同的范围。如果是这种情况,那么使用它也许是一个不错的选择。
      【解决方案3】:

      详细研究问题后发现如下:

      1. 我可以使用SET CONTEXT_INFO,但我必须注入一些 SQL 来解决问题。

      2. 最好的选择是不在查找表中存储本地化数据。相反,存储一些标识字符串,并在应用程序中使用自定义本地化逻辑将字符串与本地化数据匹配。对于 .NET 框架,如果我想从数据库中检索本地化信息,它将通过使用资源和自定义资源提供程序来实现。

      感谢您的回答。

      【讨论】:

        猜你喜欢
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-04
        • 2012-09-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 2013-02-03
        相关资源
        最近更新 更多