SQL*_*ing 4 performance sql-server check-constraints query-performance
我有两列看起来像这样:
Start_Post End_Post ---------- -------- 102+20.45 153+19.22 120+21.25 220+25.30 ……
我想对每一列引入一个约束:
Start_PosEnd_Pos所有值均以英尺为单位并遵循特殊格式。这是一个建筑惯例,我不是专家,但据我所知,1+00 是 100 英尺。从本质上讲,取上述范围 100+50.30 到 150+20.65 意味着距离为 4970 英尺。我所做的只是删除加号并减去两个数字。希望这是有道理的。
有没有办法在保持格式的同时定义这个约束?
假设左侧的数字以+100 为单位进行测量,您或许可以创建如下约束:
CREATE TABLE dbo.SurveyData
(
StartPostStation int NOT NULL
, StartPostPlus decimal(38,3) NOT NULL
, EndPostStation int NOT NULL
, EndPostPlus decimal(38,3) NOT NULL
, CONSTRAINT StartMin
CHECK ((StartPostStation * 100 + StartPostPlus) > 100*100+50.3)
, CONSTRAINT StartMax
CHECK ((StartPostStation * 100 + StartPostPlus) < 150*100+20.65)
, CONSTRAINT EndMin
CHECK ((EndPostStation * 100 + EndPostPlus) > 150*100+60.3)
, CONSTRAINT EndMax
CHECK ((EndPostStation * 100 + EndPostPlus) < 500*100+20.75)
);
Run Code Online (Sandbox Code Playgroud)
但是,这不允许动态约束,表中的所有行都将受限于这些度量,这实际上可能正是您所需要的。
如果您需要为每个独立行动态调整约束,您可以这样做:
CREATE TABLE dbo.SurveyData
(
StartPostStation int NOT NULL
, StartPostPlus decimal(38,3) NOT NULL
, EndPostStation int NOT NULL
, EndPostPlus decimal(38,3) NOT NULL
, CONSTRAINT StartMin
CHECK ((StartPostStation * PostUnits + StartPostPlus) > MinStartPost * PostUnits + MinStartPostPlus)
, CONSTRAINT StartMax
CHECK ((StartPostStation * PostUnits + StartPostPlus) < MaxStartPost * PostUnits + MaxStartPostPlus)
, CONSTRAINT EndMin
CHECK ((EndPostStation * PostUnits + EndPostPlus) > MinEndPost * PostUnits + MinEndPostPlus)
, CONSTRAINT EndMax
CHECK ((EndPostStation * PostUnits + EndPostPlus) < MaxEndPost * PostUnits + MaxEndPostPlus)
, MinStartPost int NOT NULL
, MinStartPostPlus decimal(38,3) NOT NULL
, MaxStartPost int NOT NULL
, MaxStartPostPlus decimal(38,3) NOT NULL
, MinEndPost int NOT NULL
, MinEndPostPlus decimal(38,3) NOT NULL
, MaxEndPost int NOT NULL
, MaxEndPostPlus decimal(38,3) NOT NULL
, PostUnits int NOT NULL
);
INSERT INTO dbo.SurveyData (StartPostStation, StartPostPlus, EndPostStation, EndPostPlus
, MinStartPost, MinStartPostPlus, MaxStartPost, MaxStartPostPlus
, MinEndPost, MinEndPostPlus, MaxEndPost, MaxEndPostPlus
, PostUnits)
VALUES (120, 49.2, 175, 80.5 --measurements
, 100, 50.3, 150, 20.65 --valid start post range
, 150, 60.3, 500, 20.75 --valid end post range
, 100); --units per post
Run Code Online (Sandbox Code Playgroud)
选择数据如下所示:
SELECT StartPost = CONVERT(varchar(10), sd.StartPostStation) + '+' + CONVERT(varchar(50), sd.StartPostPlus)
, EndPost = CONVERT(varchar(10), sd.EndPostStation) + '+' + CONVERT(varchar(50), sd.EndPostPlus)
FROM dbo.SurveyData sd;
Run Code Online (Sandbox Code Playgroud)
结果,像这样:
+------------+------------+ | 开始发布 | 终点站 | +------------+------------+ | 120+49.200 | 175+80.500 | +------------+------------+
post 列被分成两部分,使我们能够使用正确的数据类型来存储数字数据。如果我们尝试存储175+80.50在单个字段中,我们最终会使用一个varchar(x)列,它允许坏数据的各种可能性,例如tee+27.-1很难全面防止的。因此,我们将车站存储在一列中,并将与该车站的偏移量存储在下一列中。在屏幕上或报告中向人类展示这些数据时,我们将使用上面显示的连接版本。