code_junkie

Best-practices for localizing a SQL Server (2005/2008) database

Nov 12th, 2011
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.61 KB | None | 0 0
  1. Product
  2. ID (int, identity)
  3. Name (XML ...)
  4. Description (XML ...)
  5.  
  6. <localization>
  7. <text culture="sv-SE">Detta är ett namn</text>
  8. <text culture="en-EN">This is a name</text>
  9. </localization>
  10.  
  11. SELECT *
  12. From Product
  13. Where Product.ID = 10
  14.  
  15. SELECT *
  16. From Product
  17. Where Product.ID = 10 AND Product.cultureID = 1
  18.  
  19. <l10n>
  20. <text xml:lang="sv-SE">Detta är ett namn</text>
  21. <text xml:lang="en-EN">This is a name</text>
  22. </l10n>
  23.  
  24. SELECT Name.value('(l10n/text[lang()="en"])[1]', 'NVARCHAR(MAX)')
  25. FROM Product
  26. WHERE Product.ID=10;
  27.  
  28. CREATE TABLE [dbo].[Lang_en_US_Msg](
  29. [MsgId] [int] IDENTITY(1,1) NOT NULL,
  30. [MsgKey] [varchar](200) NOT NULL,
  31. [MsgTxt] [varchar](2000) NOT NULL,
  32. [MsgDescription] [varchar](2000) NOT NULL,
  33. CONSTRAINT [PK_Lang_US-us__Msg] PRIMARY KEY CLUSTERED
  34. (
  35. [MsgId] ASC
  36. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  37. ) ON [PRIMARY]
  38.  
  39. GO
  40.  
  41. CREATE TABLE [dbo].[User](
  42. [UserId] [int] IDENTITY(1,1) NOT NULL,
  43. [FirstName] [varchar](50) NOT NULL,
  44. [MiddleName] [varchar](50) NULL,
  45. [LastName] [varchar](50) NULL,
  46. [DomainName] [varchar](50) NULL,
  47. CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
  48. (
  49. [UserId] ASC
  50. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  51. ) ON [PRIMARY]
  52.  
  53. CREATE TABLE [dbo].[UserSetting](
  54. [UserSettingId] [int] IDENTITY(1,1) NOT NULL,
  55. [UserId] [int] NOT NULL,
  56. [CultureInfo] [varchar](50) NOT NULL,
  57. [GuiLanguage] [varchar](10) NOT NULL,
  58. CONSTRAINT [PK_UserSetting] PRIMARY KEY CLUSTERED
  59. (
  60. [UserSettingId] ASC
  61. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  62. ) ON [PRIMARY]
  63.  
  64. ALTER TABLE [dbo].[UserSetting] ADD CONSTRAINT [DF_UserSetting_CultureInfo] DEFAULT ('fi-FI') FOR [CultureInfo]
  65. GO
  66.  
  67. CREATE TABLE [dbo].[Lang_fi_FI_Msg](
  68. [MsgId] [int] IDENTITY(1,1) NOT NULL,
  69. [MsgKey] [varchar](200) NOT NULL,
  70. [MsgTxt] [varchar](2000) NOT NULL,
  71. [MsgDescription] [varchar](2000) NOT NULL,
  72. [DbSysNameForExpansion] [varchar](50) NULL,
  73. CONSTRAINT [PK_Lang_Fi-fi__Msg] PRIMARY KEY CLUSTERED
  74. (
  75. [MsgId] ASC
  76. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  77. ) ON [PRIMARY]
  78.  
  79. CREATE PROCEDURE [dbo].[procGui_GetPageMsgs]
  80. @domainUser varchar(50) , -- the domain_user performing the action
  81. @msgOut varchar(4000) OUT, -- the (error) msg to be shown to the user
  82. @debugMsgOut varchar(4000) OUT , -- this variable holds the debug msg to be shown if debug level is enabled
  83. @ret int OUT -- the variable indicating success or failure
  84.  
  85. AS
  86. BEGIN -- proc start
  87. SET NOCOUNT ON;
  88.  
  89. declare @procedureName varchar(200)
  90. declare @procStep varchar(4000)
  91.  
  92.  
  93. set @procedureName = ( SELECT OBJECT_NAME(@@PROCID))
  94. set @msgOut = ' '
  95. set @debugMsgOut = ' '
  96. set @procStep = ' '
  97.  
  98.  
  99. BEGIN TRY --begin try
  100. set @ret = 1 --assume false from the beginning
  101.  
  102. --===============================================================
  103. --debug set @procStep=@procStep + 'GETTING THE GUI LANGUAGE FOR THIS USER '
  104. --===============================================================
  105.  
  106. declare @guiLanguage nvarchar(10)
  107.  
  108.  
  109.  
  110.  
  111. if ( @domainUser is null)
  112. set @guiLanguage = (select Val from AppSetting where Name='guiLanguage')
  113. else
  114. set @guiLanguage = (select GuiLanguage from UserSetting us join [User] u on u.UserId = us.UserId where u.DomainName=@domainUser)
  115.  
  116. set @guiLanguage = REPLACE ( @guiLanguage , '-' , '_' ) ;
  117.  
  118.  
  119. --===============================================================
  120. set @procStep=@procStep + ' BUILDING THE SQL QUERY '
  121. --===============================================================
  122.  
  123. DECLARE @sqlQuery AS nvarchar(2000)
  124. SET @sqlQuery = 'SELECT MsgKey , MsgTxt FROM dbo.lang_' + @guiLanguage + '_Msg'
  125.  
  126.  
  127. --===============================================================
  128. set @procStep=@procStep + 'EXECUTING THE SQL QUERY'
  129. --===============================================================
  130. print @sqlQuery
  131.  
  132. exec sp_executesql @sqlQuery
  133.  
  134. set @debugMsgOut = @procStep
  135. set @ret = @@ERROR
  136.  
  137.  
  138. END TRY --end try
  139.  
  140. BEGIN CATCH
  141. PRINT 'In CATCH block.
  142. Error number: ' + CAST(ERROR_NUMBER() AS varchar(10)) + '
  143. Error message: ' + ERROR_MESSAGE() + '
  144. Error severity: ' + CAST(ERROR_SEVERITY() AS varchar(10)) + '
  145. Error state: ' + CAST(ERROR_STATE() AS varchar(10)) + '
  146. XACT_STATE: ' + CAST(XACT_STATE() AS varchar(10));
  147.  
  148. set @msgOut = 'Failed to execute ' + @sqlQuery
  149. set @debugMsgOut = ' Error number: ' + CAST(ERROR_NUMBER() AS varchar(10)) +
  150. 'Error message: ' + ERROR_MESSAGE() + 'Error severity: ' + CAST(ERROR_SEVERITY() AS varchar(10)) +
  151. 'Error state: ' + CAST(ERROR_STATE() AS varchar(10)) + 'XACT_STATE: ' + CAST(XACT_STATE() AS varchar(10))
  152.  
  153. --record the error in the database
  154. --debug
  155. --EXEC [dbo].[procUtils_DebugDb]
  156. -- @DomainUser = @domainUser,
  157. -- @debugmsg = @debugMsgOut,
  158. -- @ret = 1,
  159. -- @procedureName = @procedureName ,
  160. -- @procedureStep = @procStep
  161.  
  162. -- set @ret = 1
  163.  
  164. END CATCH
  165.  
  166.  
  167. return @ret
  168. END --procedure end
  169.  
  170. Given a users culture is "sv-se"
  171. When the user views a post list
  172. It should list posts only in "sv-se" culture
  173.  
  174. SELECT * FROM Post WHERE CultureUI IN ('sv-se', 'en-us')
  175.  
  176. Label1.Text = GetLocalResourceObject("TokenStoredInDatabase").ToString()
  177.  
  178. * id
  179. * price
  180. * stocklevel
  181. * active
  182. * name
  183. * shortdescription
  184. * longdescription
  185.  
  186. * id
  187. * products_id
  188. * name
  189. * shortdescription
  190. * longdescription
  191.  
  192. string query = "";
  193. if(string.IsNullOrEmpty(culture)) {
  194. // No culture specified, no join needed.
  195. query = "SELECT p.price, p.name, p.shortdescription FROM products p WHERE p.price > ?Price";
  196. } else {
  197. query = "SELECT p.price, case when pg.name is null then p.name else pg.name end as 'name', case when pg.shortdescription is null then p.shortdescription else pg.shortdescription end as 'shortdescription' FROM products p"
  198. + " LEFT JOIN products_globalization pg ON pg.products_id = p.id AND pg.culture = ?Culture"
  199. + " WHERE p.price > ?Price";
  200. }
Add Comment
Please, Sign In to add comment