0

I ran into a problem this days. In my MS SQL Database I have a table of articles (details of them like insert date, insert user and other staffs) and one table with the body of articles in multiple languages. I want that the articles body to be in user preferred language. But not all the articles are in all languages. So, would be nice, first to search for the article in user's preferred language and, if not exists, to get the body in first language it is.

For this, I use a function. The WHERE clause is like this:

WHERE   [tblBody].[Language] = @Language AND
        [tblTitle].[Language] = @Language

but would be nice if it would be like this: SELECT (if body is in my preferred language get that body; else give me one (maybe I understood it))

I hope you understood what I want to do and witch are my problems.

Thank you in advance!

UPDATE

This is my actual query which needs modifications:

 ALTER FUNCTION [fx_GetNews]
(   
    @MinimumPermission INT,
    @UserID UNIQUEIDENTIFIER,
    @OwnerID  UNIQUEIDENTIFIER = NULL,
    @Title NVARCHAR(250) = NULL,
    @Body VARCHAR(150) = NULL,
    @InsertDateStart DATETIME = NULL,
    @InsertDateEnd DATETIME = NULL,
    @CreatedByUserID UNIQUEIDENTIFIER = NULL,
    @ExpirationDate DATETIME = NULL,
    @Language VARCHAR(150)
)
RETURNS @News TABLE 
(
    [Id] UNIQUEIDENTIFIER
    ,[OwnerID] UNIQUEIDENTIFIER
    ,[Title] NVARCHAR(250)
    ,[TitlePictureUrl] VARCHAR(150)
    ,[Body] NVARCHAR(max)
    ,[Visible] BIT
    ,[InsertDate] DATETIME
    ,[CreatedByUserId] UNIQUEIDENTIFIER
    ,[ModifiedDate] DATETIME
    ,[ModifiedByUserId] UNIQUEIDENTIFIER
    ,[ModifiedByPerson] VARCHAR(250)
    ,[ExpirationDate] DATETIME
    ,[CreatedByPerson] VARCHAR(250)
    ,[Permission] INT
)
AS
BEGIN
    INSERT INTO @News
           ([Id]
           ,[OwnerID]
           ,[Title]
           ,[TitlePictureUrl]
           ,[Body]
           ,[Visible]
           ,[InsertDate]
           ,[CreatedByUserId]
           ,[ModifiedDate]
           ,[ModifiedByUserId]
           ,[CreatedByPerson]
           ,[ModifiedByPerson]
           ,[ExpirationDate]
           ,[Permission])
        SELECT
                [dbo].[tblNews].[Id]
               ,[dbo].[tblNews].[OwnerID]
               ,CAST([tblTitle].[Text] AS VARCHAR(150))
               ,[dbo].[tblNews].[TitlePictureUrl]
               ,[tblBody].[Text]
               ,[dbo].[tblNews].[Visible]
               ,[dbo].[tblNews].[InsertDate]
               ,[dbo].[tblNews].[CreatedByUserId]
               ,[dbo].[tblNews].[ModifiedDate]
               ,[dbo].[tblNews].[ModifiedByUserId]
               ,[dbo].[tblNews].[CreatedByPerson]
               ,[dbo].[tblNews].[ModifiedByPerson]
               ,[dbo].[tblNews].[ExpirationDate]
               ,[eportofolii].[fx_GetPermissionForObject] (@UserID, [dbo].[tblNews].[ID], 1, 1)
           FROM [dbo].[tblNews] 
                    INNER JOIN [dbo].[tblAdmTranslateText] AS [tblBody] ON
                        [tblBody].[OwnerID] = [dbo].[tblNews].[ID]
                    INNER JOIN [dbo].[tblAdmTranslateText] AS [tblTitle] ON
                        [tblTitle].[OwnerID] = [dbo].[tblNews].[ID]
        WHERE
            [eportofolii].[fx_GetPermissionForObject] (@UserID, [dbo].[tblNews].[ID], 1, 1) >= @MinimumPermission AND
            ([dbo].[tblNews].[OwnerID] = ISNULL(@OwnerID, [dbo].[tblNews].[OwnerID]) OR [dbo].[tblNews].[OwnerID] IS NULL) AND
            [tblTitle].[Text] LIKE '%' + ISNULL(@Title, '') + '%' AND
            [tblBody].[Text] LIKE '%' + ISNULL(@Body, '') + '%' AND
            ([dbo].[tblNews].[InsertDate] BETWEEN ISNULL(@InsertDateStart, ([dbo].[tblNews].[InsertDate] - 7)) AND ISNULL(@InsertDateEnd, [dbo].[tblNews].[InsertDate] + 1)) AND
            [dbo].[tblNews].[CreatedByUserID] = ISNULL(@CreatedByUserID, [dbo].[tblNews].[CreatedByUserID]) AND
            ([dbo].[tblNews].[ExpirationDate] > ISNULL(@ExpirationDate, GETDATE() - 1) OR [dbo].[tblNews].[ExpirationDate] IS NULL) AND
            [tblBody].[UDF_2] = 'Body' AND 
            [tblTitle].[UDF_2] = 'Title' AND 
            [tblBody].[UDF_1] = 'News' AND 
            [tblTitle].[UDF_1] = 'News' AND
            [tblBody].[Language] = @Language AND
            [tblTitle].[Language] = @Language
        ORDER BY [InsertDate] DESC
    RETURN
END

The problem is here at the end:

[tblBody].[Language] = @Language AND
[tblTitle].[Language] = @Language

Thank you!

4

4 回答 4

2
;WITH x AS 
(
   SELECT b.[Language], /* other columns from b */
     rn = ROW_NUMBER() OVER (PARTITION BY b.article_id_of_some_kind
       ORDER BY CASE WHEN t.[Language] = @Language THEN 1 ELSE 2 END)
   FROM dbo.tblBody AS b
   INNER JOIN dbo.tblLanguage AS l
    ON b.LanguageID = l.LanguageID -- guessing here
)
SELECT /* cols */ FROM x WHERE rn = 1;

This will return an arbitrary language if the preferred language is not available. You can further refine that by modifying the inner ORDER BY.

于 2013-03-30T20:57:54.693 回答
0

What you want to do is a bit complicated. You want to return articles in the desired language, if present, and in another language if not.

For this, a window function is quite useful:

select t.*
from (select blah,
             max(case when [tblBody].[Language] = @Language then 1 else 0 end) over (partition by article) as HasLanguage       
      from whatever
      where [tblTitle].[Language] = @Language
     ) t
where HasLanguage = 1 or [tblBody].[Language] <> @Language 
于 2013-03-30T20:57:48.753 回答
0
select B.*
from bodies as B
where exists (
  select 1 from (
    select b.article, coalesce( u.language, b.language ) as language
    from bodies as b 
    left join users as u
    on b.language = u.language
    and u.user = @user
    where b.article = @article
    and b.default_language = 'TRUE' -- or whatever
  ) as A
  on A.article = B.Article
  and A.language = B.language
)

You have to choose between two languages: the user's language and the article's language. you could use UNION or coalesce (because an outer join is a kind of a union), and the latter is simpler.

于 2013-03-30T22:36:13.280 回答
-1

One option is to use the MSSQL "COALESCE" function:

Another might be to use a CASE block.

于 2013-03-30T20:54:28.733 回答