Sql 如何从每个语言都有行的表中获取默认语言行?

Sql 如何从每个语言都有行的表中获取默认语言行?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,假设我有这两个表,我有两种语言,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, I

假设我有这两个表,我有两种语言,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

但是第四个不起作用?

您在表中没有价值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

如果默认值存储在转换表中,则通常必须连接到转换表两次:

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
返回第一个非空参数-因此,如果连接成功,它会选择
pt
行中的值,如果第一个连接失败,则选择
ptDef
行中的值


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

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

(如果您想使用这种语言,您可以存储默认语言,并防止此语言的翻译出现在翻译表中。但这通常是过火的-通常,所有默认语言都是单一语言。

是的,我想选择“en”,在这种情况下,您可以,只要您的默认值为v值不会更改。如果默认值更改,则必须重新编写代码。我通常建议将默认语言值存储在“行”(在本例中,存储在
xProduct
表中)。这样,您可以确保它们存在,并且很容易回到默认值(使用
左联接
到翻译表和
合并
)@达米恩,不信的人,这是不可能的吗schema@user960567-建议更改模式。@MartinSmith,可以用新模式为我提供答案吗?如果我有3种语言,那么我需要另一个连接吗?@user960567-不,第一个连接是您希望获得翻译的语言(它与您原来的连接相同,依赖于
@lang
,但它需要是
左连接
,而不是
内部连接
,因为我们希望它能够失败)。第二个连接是默认语言。我需要使用Xproduct上所有字段的合并