0

これらの2つのテーブルがあり、enとarの2つの言語があるとします。

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番目のものは機能していませんか?

4

2 に答える 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ます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

(これをやりすぎたい場合は、デフォルトがどの言語であるかを保存し、この言語の翻訳が翻訳テーブルに表示されないようにすることができます。ただし、これは通常、やり過ぎです-通常、すべてのデフォルトは単一にありますとにかく言語。

于 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

SQLFiddleデモ

于 2012-11-26T08:41:59.337 に答える