SQL Server约束增强的两点建议

2016-02-19 09:21 5 1 收藏

下面是个简单易学的SQL Server约束增强的两点建议教程,图老师小编详细图解介绍包你轻松学会,喜欢的朋友赶紧get起来吧!

【 tulaoshi.com - 编程语言 】

在许多情况下,对外键使用更复杂的逻辑表达式是非常有用的。 此外,在某些情况下能够在索引视图创建约束也将非常实用。 我将举例说明,同时我希望针对此文的投票链接会尽快加上。
当外键中需要更为复杂的逻辑表达式时
考虑下面的简单常识: 您的设备的最大电流不能超过您插入到它的电路的最大电流。 假设下面的表存储电路和设备数据:
代码如下:

CREATE TABLE Data.Curcuits(CurcuitID INT NOT NULL
CONSTRAINT PK_Curcuits PRIMARY KEY,
MaximumCurrent INT NOT NULL,
Description VARCHAR(100) NOT NULL);
GO
INSERT INTO Data.Curcuits(CurcuitID,
MaximumCurrent,
Description)
SELECT 1, 25, 'Deck and Garage';
GO
CREATE TABLE Data.Devices(DeviceID INT NOT NULL
CONSTRAINT PK_Devices PRIMARY KEY,
CurcuitID INT NULL,
MaximumCurrent INT NOT NULL,
Description VARCHAR(100) NOT NULL,
CONSTRAINT FK_Devices_Curcuits FOREIGN KEY(CurcuitID)
REFERENCES Data.Curcuits(CurcuitID)
);
GO

It would be very convenient to issue a simple command and implement this business rule:
一个非常简便的命令就可能实现这个业务规则:
ALTER TABLE Data.Devices ADD CONSTRAINT FK_Devices_Curcuits
FOREIGN KEY(CurcuitID, MaximumCurrent)
REFERENCES Data.Curcuits(CurcuitID, MaximumCurrent)
MATCH ON((Data.Devices.CurcuitID = Data.Curcuits.CurcuitID) AND
(Data.Devices.MaximumCurrent = Data.Curcuits.MaximumCurrent));
However, it is not supported, so I need to use a workaround, one more column and three constraints instead of one, as follows:
然而,该语句并不被支持,所以必须采用其他办法——多增加一列约束,使用3个而不是1个约束,如下所示:
ALTER TABLE Data.Curcuits
ADD CONSTRAINT UNQ_Curcuits UNIQUE(CurcuitID, MaximumCurrent);
GO
ALTER TABLE Data.Devices ADD CurcuitMaximumCurrent INT NULL;
GO
ALTER TABLE Data.Devices DROP CONSTRAINT FK_Devices_Curcuits;
GO
ALTER TABLE Data.Devices ADD CONSTRAINT FK_Devices_Curcuits
FOREIGN KEY(CurcuitID, CurcuitMaximumCurrent)
REFERENCES Data.Curcuits(CurcuitID, MaximumCurrent)
ON UPDATE CASCADE;
GO
ALTER TABLE Data.Devices
ADD CONSTRAINT CHK_Devices_SufficientCurcuitMaximumCurrent
CHECK(CurcuitMaximumCurrent = MaximumCurrent);
GO
You can verify that the constraints work:
你可以验证该约束有效:
INSERT INTO Data.Devices(DeviceID,
CurcuitID,
MaximumCurrent,
CurcuitMaximumCurrent,
Description)
SELECT 1, 1, 50, 25, 'Electric car charger'
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "CHK_Devices_SufficientCurcuitMaximumCurrent". The conflict occurred in database "Test", table "data.Devices".
The statement has been terminated.
INSERT 语句和CHECK约束"CHK_Devices_SufficientCurcuitMaximumCurrent"发生冲突。 该冲突发生在数据库"Test"的"data.Devices"表。
该语句被终止执行。
As you have seen, the implementation of a very simple and very common business rule is quite involved, because such business rules are not directly supported by the database engine.
可以看出,一个非常简单而普通的业务规则实现起来也相当繁杂,因为数据库引擎并不直接支持这种业务规则。
When you want to create constraints on indexed views
在索引视图上创建约束
Even when your database guarantees that “the maximum current of your device cannot exceed the maximum current of the circuit you plug it into”, it is not good enough. Consider the following sample data:
尽管数据库保证“您的设备的最大电流不能超过您插入到它的电路的最大电流”,但这还不够。请看下列示例数据:
INSERT INTO Data.Devices(DeviceID,
CurcuitID,
MaximumCurrent,
CurcuitMaximumCurrent,
Description)
SELECT 2, 1, 15, 25, 'ShopVac';
INSERT INTO Data.Devices(DeviceID,
CurcuitID,
MaximumCurrent,
CurcuitMaximumCurrent,
Description)
SELECT 3, 1, 15, 25, 'Miter Saw';
The database structure allows to plug more than one device into a circuit, which is correct, but if you turn both devices on, their combined maximum current exceeds the circuit's maximum current. To enforce this business rule, it would be natural to create an indexed view, so that the database guarantees that the totals are always correct:
数据库中的数据表明可以插入一个以上的设备到电路,这没有错,可是当所有的设备都打开时,它们的最大电流之和会超过电路最大电流。为了加强这个业务规则,很自然的会创建一个索引视图以使数据库保证电流之和总是正确的。
CREATE VIEW Data.TotalMaximumCurrentPerCircuit WITH SCHEMABINDING
AS
SELECT d.CurcuitID,
c.MaximumCurrent AS CircuitMaximumCurrent,
SUM(d.MaximumCurrent) AS TotalMaximumCurrent,
COUNT_BIG(*) AS NumDevices
FROM Data.Devices d JOIN Data.Curcuits c ON d.CurcuitID = c.CurcuitID
GROUP BY d.CurcuitID, c.MaximumCurrent;
GO
CREATE UNIQUE CLUSTERED INDEX Data_TotalMaximumCurrentPerCircuit
ON Data.TotalMaximumCurrentPerCircuit(CurcuitID);
GO
If I could create a check constraint on that indexed view, I would be all set:
如果能在该索引视图上创建一个约束,我将进行这样的设置:
ALTER VIEW Data.TotalMaximumCurrentPerCircuit
ADD CONSTRAINT CHK_TotalMaximumCurrentPerCircuit_ValidCurcuit
CHECK(TotalMaximumCurrent = CircuitMaximumCurrent)
Instead, I need to use triggers or rather contrived kludges. A built in native support for such quite common business rules would increase the usefulness of SQL Server.
实际上,我必须使用触发器或者精心拼凑Check约束来实现。如果数据库内置支持这种相当普遍的业务规则,那将会增加SQL Server的实用性 。

来源:http://www.tulaoshi.com/n/20160219/1590460.html

延伸阅读
怎么挑选合适的护手霜 根据年龄来选购护手霜 护手霜的使用在年龄上也是有区别的,从年龄上来讲,比较年轻的美眉们,在挑选护手霜的时候,可以选择质地水润的保湿效果好的护手霜,给双手一个保湿补水的护理,也能够避免双手粗糙干燥。而稍微上了年纪的女性朋友们,选购护手霜就应该选购抗衰老型的护手霜,尤其是手背长出斑点的美眉们,可以...
标签: 怀孕
顺产的宝宝更聪明是吗?顺产一定要侧切吗?顺产会影响以后的夫妻生活吗?关于这些问题的答案你真的清楚吗?下面我们就来看看专家是怎么回答这些问题的。 1 据说,自然分娩时,宝贝被阴道挤过之后,会更聪明,这是真的吗? 医生回答:虽然非常鼓励自然分娩,但是确实没有这个说法。目前有研究认为婴儿从0岁到3岁是智力形成的关键,一直到8岁...
1.在厨房里的家具应该选择封闭式的,这样就可以让各种厨具收入其中,看起来也更加整齐。在设计厨房橱柜的时候最好是设计成抽屉式或者是推拉式的,这样拿取物品的时候就变得很方便。吊柜操作平台之间的间隙可以用来放取一些烹饪中所需的用具。 2.在厨房装修上,不要过于复杂的设计,只要按照所需的流程来进行设计装修就要可以了。在...
怀孕前检查牙齿需注意两点     怀孕前去医院检查牙齿必须了解以下两点知识,这样自身和孩子的健康来说很重要。     ①检查牙齿是否洁净。要确保牙齿的洁净,否则怀孕后可能会因牙斑菌、牙结石过多而导致牙齿问题。最好是能洗一次牙,把口腔中的细菌去除掉,保护牙龈。     ...
冰箱怎么保养 定期清扫压缩机和冷凝器 压缩机和冷凝器是冰箱的重要制冷部件,如果沾上灰尘会影响散热,导致零件使用寿命缩短、冰箱制冷效果减弱。所以,要定期检查它们是否脏了,脏了就要清扫。当然,使用完全平背设计的冰箱不需考虑这个问题。因为挂背式冰箱的冷凝器、压缩机都裸露在外面,极易沾上灰尘、蜘蛛网等。而平背式冰箱的冷凝器...

经验教程

808

收藏

23
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部