可以使用视图和唯一索引在表之间创建独特的索引。
但我有一个问题。
假设有两个(或三个)表。
Company
- Id
- Name
Brand
- Id
- CompanyId
- Name
- Code
Product
- Id
- BrandId
- Name
- Code
我希望确保唯一性,即以下组合的唯一性:
Company / Brand.Code
和
Company / Brand.Product/Code
是独一无二的。
CREATE VIEW TestView
WITH SCHEMABINDING
AS
SELECT b.CompanyId, b.Code
FROM dbo.Brand b
UNION ALL
SELECT b.CompanyId, p.Code
FROM dbo.Product p
INNER JOIN dbo.Brand b ON p.BrandId = b.BrandId
视图创建成功。
CREATE UNIQUE CLUSTERED INDEX UIX_UniquePrefixCode
ON TestView(CompanyId, Code)
由于使用了UNION
运算符,此操作失败。
我该如何解决这种情况?
基本上,在公司内,品牌/产品
的代码都不能重复。
注:
我遇到的错误是:
Msg 10116,级别16,状态1,第3行无法在视图“XXXX.dbo.TestView”上创建索引,因为它包含一个或多个UNION、INTERSECT或EXCEPT运算符。考虑为原始视图的每个输入查询创建单独的索引视图,该查询是UNION、INTERSECT或EXCEPT运算符的输入。
注2:
当我使用子查询时,我会收到以下错误:
Msg 10109,级别16,状态1,第3行无法在视图“XXXX.dbo.TestView”上创建索引,因为它引用了派生表“a”(由FROM子句中的SELECT语句定义)。考虑删除对派生表的引用或不对视图进行索引。
注3:
因此,给定品牌:
来自@spaghettidba的答案。
INSERT INTO Brand
(
Id,
CompanyId,
Name,
Code
)
VALUES
(1, 1, 'Brand 1', 100 ),
(2, 2, 'Brand 2', 200 ),
(3, 3, 'Brand 3', 300 ),
(4, 1, 'Brand 4', 400 ),
(5, 3, 'Brand 5', 500 )
INSERT INTO Product
(
Id,
BrandId,
Name,
Code
)
VALUES
(1001, 1, 'Product 1001', 1 ),
(1002, 1, 'Product 1002', 2 ),
(1003, 3, 'Product 1003', 3 ),
(1004, 3, 'Product 1004', 301 ),
(1005, 4, 'Product 1005', 5 )
期望的是,如果我们扩展结果,品牌代码+公司
或产品代码+公司
应该是唯一的。
Company / Brand|Product Code
1 / 100 <-- Brand
1 / 400 <-- Brand
1 / 1 <-- Product
1 / 2 <-- Product
1 / 5 <-- Product
2 / 200 <-- Brand
3 / 300 <-- Brand
3 / 500 <-- Brand
3 / 3 <-- Product
3 / 301 <-- Brand
没有重复。如果我们有一个品牌和产品使用相同的代码。
INSERT INTO Brand
(
Id,
CompanyId,
Name,
Code
)
VALUES
(6, 1, 'Brand 6', 999)
INSERT INTO Product
(
Id,
BrandId,
Name,
Code
)
VALUES
(1006, 2, 'Product 1006', 999)
该产品属于另一家公司所有,因此我们收到
Company / Brand|Product Code
1 / 999 <-- Brand
2 / 999 <-- Product
这是独一无二的。
但如果你有两个品牌,只有一个产品。
INSERT INTO Brand
(
Id,
CompanyId,
Name,
Code
)
VALUES
(7, 1, 'Brand 7', 777)
(8, 1, 'Brand 8', 888)
INSERT INTO Product
(
Id,
BrandId,
Name,
Code
)
VALUES
(1007, 8, 'Product 1008', 777)
这将产生
Company / Brand|Product Code
1 / 777 <-- Brand
1 / 888 <-- Brand
1 / 777 <-- Product
这是不被允许的。
希望这样说有意义。
注释 4:
@spaghettidba的回答解决了跨表问题,第二个问题是品牌表本身存在重复。
我通过在品牌表上创建单独的索引来解决了这个问题:
CREATE UNIQUE NONCLUSTERED INDEX UIX_UniquePrefixCode23
ON Brand(CompanyId, Code)
WHERE Code IS NOT NULL;