Sql 如何从每个语言都有行的表中获取默认语言行?
假设我有这两个表,我有两种语言,en和arSql 如何从每个语言都有行的表中获取默认语言行?,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
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上所有字段的合并