0

假设我有这 2 个表,并且我有 2 种语言,en 和 ar,

CREATE TABLE [dbo].[xProduct](
        [ID] [int] IDENTITY(1,1) NOT NULL,
    [Model] [varchar](255) NULL,
 CONSTRAINT [PK_xProduct] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[xProductT](
    [ID] [int] IDENTITY(1,1) NOT NULL,
        [PID] [int] NOT NULL,
    [Lang] [varchar](2) NOT NULL,
    [Name] [nvarchar](255) NULL,
    [Description] [nvarchar](255) NULL,
    [IsDefault] [bit] NULL,
 CONSTRAINT [PK_xProductT] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]



-- xProduct
ID  Model
1   SVE11611
2   SVE11711

-- xProductT
ID  PID Lang       Name                        Description         IsDefault
1   1   EN  Sony Vaio E11611    Sony Vaio E11611 Description         1
2   1   AR  سوني فايو E11611    وصف سوني فايو E11611              NULL
3   2   EN  Sony Vaio E11711    Sony Vaio E11711 Description        1

这是我尝试过的,

declare @lang varchar(2) ='en'
declare @id int =1
-- Works and give a single row
Select p.*,pt.* from xProduct p inner join xProductT pt on (p.id = pt.pid and pt.lang = @lang)where p.id=@id    

set @lang  ='ar'
set  @id =1    
-- Works and give a single row
Select p.*,pt.* from xProduct p inner join xProductT pt on (p.id = pt.pid and pt.lang = @lang)where p.id=@id

set @lang  ='en'
set  @id =2    
-- Works and give a single row
Select p.*,pt.* from xProduct p inner join xProductT pt on (p.id = pt.pid and pt.lang = @lang)where p.id=@id

set @lang  ='ar'
set  @id =2    
-- Does not work I need to select the default one
Select p.*,pt.* from xProduct p inner join xProductT pt on (p.id = pt.pid and pt.lang = @lang)where p.id=@id

但是第四个不工作?

4

2 回答 2

2

如果默认值存储在那里,您通常必须加入转换表两次:

set @lang  ='ar'
set  @id =2    
-- Does not work I need to select the default one
Select
    p.*,COALESCE(pt.Name,ptDef.Name) as Name
from
    xProduct p
       left join
    xProductT pt
       on
         (p.id = pt.pid and pt.lang = @lang)
       inner join
    xProductT ptDef
       on
         (p.id = ptDef.pid and ptDef.IsDefault=1)
where p.id=@id

返回第COALESCE一个非 NULL 参数 - 因此pt,如果连接成功,或者 fromptDef是第一个连接失败,这将导致它更喜欢行中的值。


正如我在评论中指出的那样,我通常会推荐这种模式:

CREATE TABLE [dbo].[xProduct](
        [ID] [int] IDENTITY(1,1) NOT NULL,
    [Model] [varchar](255) NOT NULL,
    [DefaultName] [nvarchar](255) NOT NULL,
    [DefaultDescription] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_xProduct] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)
) ON [PRIMARY]


CREATE TABLE [dbo].[xProductT](
    [ID] [int] IDENTITY(1,1) NOT NULL,
        [PID] [int] NOT NULL,
    [Lang] [varchar](2) NOT NULL,
    [Name] [nvarchar](255) NOT NULL,
    [Description] [nvarchar](255) NOT NULL
 CONSTRAINT [PK_xProductT] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)
) ON [PRIMARY]

因为您现在可以保证已提供默认语言版本(并且不需要向翻译表添加约束以防止将多种语言标记为默认语言)。然后它简化了查询:

 set @lang  ='ar'
set  @id =2    
-- Does not work I need to select the default one
Select
    p.*,COALESCE(pt.Name,p.DefaultName) as Name
from
    xProduct p
       left join
    xProductT pt
       on
         (p.id = pt.pid and pt.lang = @lang)
where p.id=@id

(你可以,如果你想过火,存储默认值是哪种语言,并防止该语言的翻译出现在翻译表中。但这通常是过火的 - 通常,所有默认值都在一个单一的反正语言。

于 2012-11-26T08:52:03.643 回答
0

您在xProductT表中没有价值

for @lang  ='ar' and @id =2 

尝试这样的事情:

set @lang  ='ar'
set  @id =2    
-- Does not work I need to select the default one
Select p.*,
       isnull([PID],1),
       isnull([Lang],'EN'),
       isnull([Name],'Sony Vaio E11611'),
       isnull([Description],'Sony Vaio E11611 Description'),
       isnull([IsDefault],1)

from xProduct p left join xProductT pt on (p.id = pt.pid and pt.lang = @lang)where p.id=@id

SQL Fiddle 演示

于 2012-11-26T08:41:59.337 回答