复杂的SQL Server 2008R2列约束

时间:2014-04-22 19:05:03

标签: sql sql-server sql-server-2008-r2

我有一个SQL Server 2008R2表来驱动一系列UI进程。 作为“意外的DBA”,我希望在这个表上对INSERTS和UPDATES施加一些数据完整性约束。

此表的数据完整性方面至关重要,因为如果规则有任何例外,应用程序将很快崩溃。

还需要数据完整性规则,因为此表将是相当静态的,但我们的管理员名单不是。在需要进行表维护的时候,过度的,新的或支离破碎的管理员可能不记得所有(完全记录的)规则。

-- An excerpt of the table:
CREATE TABLE [dbo].[#lkupMasterFieldList]
(
   [FieldID]        INT IDENTITY (101,1) PRIMARY KEY CLUSTERED ,  -- Unique identifier for each row                
   [FieldName]      VARCHAR( 100) NOT NULL,                       -- Output column name and/or MasterFieldList struct name.
   -- ...                                                               
   [AppFieldLabel]  VARCHAR(  50)     NULL,                       -- Name used in the app processes, esp. in creation pick lists of selectable columns. 
   [AppFieldType]   VARCHAR(  15)     NULL,                       -- When not null, one of "assignment", "job" or "-".  for grouping visible pick list fields.  Currently, the dash is used only with JobNumber to select it into the selected field list by default.
   [AppDisplayIdx]  INT           NOT NULL DEFAULT 0,             -- Sorting index value for displaying Column Picker columns in a particular order (other than the apparently random order used today.) Use negative values to ORDER BY (ASC) the default Selected list.
   -- ...   
   [Hidden]         BIT           NOT NULL DEFAULT 0,             -- Hidden = 1 if the field does not appear in the Output Columns pane.  (Typically for admins only)
   [Active]         BIT           NOT NULL DEFAULT 1,             -- Bitflag to indicate whether or not this column is still in use or is obsolete.
   [SelectString]   VARCHAR(1500)     NULL                        -- Columns or subselect query text to be included in the final dSQL SELECT statement. 
)   
GO
INSERT INTO #lkupMasterFieldList
          ( FieldName ,
            AppFieldLabel ,
            AppFieldType ,
            AppDisplayIdx ,
            Hidden ,
            Active ,
            SelectString
          )
VALUES

 -- And a data snippet, for some context...      
('AuditDate'               ,NULL                ,NULL          , 0 , 1 , 1, NULL), 
('Category'                ,'Job Category'      ,'job'         , 12, 0 , 1, '(SELECT UPPER(LabelValue) FROM tJobLabel WHERE tJobLabel.JobID = tJ.JobID AND tJobLabel.LabelTypeID = 1) AS Category,'   ), 
('Change'                  ,NULL                ,NULL          , 0 , 1 , 1, NULL), 
('ClosedDate'              ,'Job Closed Date'   ,'job'         , 19, 0 , 1, 'tJ.ClosedDate,'   ), 
('CommentID'               ,NULL                ,NULL          , 0 , 1 , 1, ''' AS CommentID,'   ), 
('Comments'                ,NULL                ,NULL          , 0 , 1 , 1, ''' AS Comments,'   ), 
('CompOn'                  ,NULL                ,NULL          , 0 , 1 , 1, NULL), 
('CreationDate'            ,'Job Created Date'  ,'job'         , 11, 0 , 1, 'tJ.CreationDate,'   ), 
('CurrentAssignee'         ,NULL                ,'assignment'  , 0 , 1 , 1, ' CASE WHEN ((tR.AssignDate IS NOT NULL) AND (tR.DispositionDate IS NULL) AND (tRL.Status = ''Active'') ) THEN 1 ELSE 0 END AS CurrentAssignee,'), 
('CurrentAssigneeWithDate' ,NULL                ,'assignment'  , 0 , 1 , 1, NULL), 
('DateLastModified'        ,NULL                ,NULL          , 0 , 1 , 1, NULL), 
('DateMods'                ,'Job Date Changes'  ,'job'         , 20, 0 , 1, '(SELECT COUNT(*) FROM tJobDueDate WHERE Jobid = tJ.Jobid) AS DateMods,'   )
 -- 
 -- 

除了创建一些独特的索引,简单的约束和默认值之外,我对这个设计领域没有多少经验。

在我为(完整)表格确定的20个左右的限制条件中,我已经得到了少数以下的工作正常。

我需要的是您对实施以下任何或所有规则的任何建议,或者表明无法完成这些规则。

  • 规则2.在INSERT时,是否可以使`DisplayName`列的默认值与为`FieldName`列输入的值相同?非常不受欢迎的当前默认值是'(未定义)'。
  • 规则3.`< column>`当且仅当(`Hidden = 1或Active = 0`)时才可以为NULL。这种类型的约束适用于三列:`AppFieldLabel,AppFieldType,SelectString`。
  • 规则5.当`NOT NULL`时,`AppFieldType`仅限于(`'job','assignment',' - '`之一)
  • 规则7.`AppDisplayIdx`默认为`max(AppDisplayIndex)+ 1
  • 规则8.如果AppFieldType =“ - ”,`AppDisplayIdx`可以小于零`
  • 规则9.如果隐藏= 1,则“AppDisplayIdx”可以为零
  • 规则10.`AppDisplayIdx`可以大于零`if(AppFieldType IS NOT NULL和AppFieldType IN('job','assignment')`
  • 规则14.`AppDisplayIdx`必须是不同的,除了零[这是由唯一的非聚集过滤索引处理。]

因此,如果我们想添加一些新字段

INSERT INTO #lkupMasterFieldList
          ( FieldName ,
            AppFieldLabel ,
            AppFieldType ,
            AppDisplayIdx ,
            Hidden ,
            Active ,
            SelectString
          )
VALUES

-- New Field 1
('Deliverable' ,NULL            , 'job'        , NULL , 0 , 1 , '(SELECT LabelValue FROM tTaskLabel AS tTL14 WHERE tTL14.TaskID = tT.TaskID AND tTL14.LabelTypeID = 2) AS Deliverable,'), 
-- New Field 2                   
('Disposition' ,NULL            , 'assignment' , NULL , 0 , 1 , 'ISNULL( (SELECT lkR.Response FROM tJobResponse tJRsp LEFT JOIN lkupResponse lkR ON tJRsp.ResponseID = lkR.ResponseID WHERE tJRsp.RLDID = tR.RLDID ), tR.Disposition ) AS Disposition, ' ), 
-- New Field 3                   
('DeptNumber'  ,'Department'    , 'dept'       ,  0   , 0 , 1 , NULL), 
-- New Field 4                   
('EmpIDOwner'  ,'Job Boss'      , 'emp'        ,  7   , 0 , 1 , 'tJ.EmpIDOwner, '   ), 
-- New Field 5                   
('AssignDate'  ,'Date Assigned' , 'date'       , -7   , 0 , 1 , 'ISNULL(tR.AssignDate, 0) AS AssignDate, ') 

-- Then for Field 1 and Field2, respectively, the 
--    AppFieldLabels would be 'Deliverable' and 'Disposition' (Rule 2) 
--    AppDisplayIdxs would be 21 and 22, (Rule 7) 

-- Field 3 fails because of any of the following:
--    AppFieldType  = 'dept' (Rule 5)
--    AppDisplayIdx = 0      (Rule 9)
--    SelectString  is NULL  (Rule 3)

-- Field 4 fails because 
--    AppFieldType = 'emp' and AppDisplayIdx = 7  (Rule 10)

-- Field 5 fails because 
--    AppFieldType = 'date' and AppDisplayIdx = -7 (Rule  8)
--
--

我怀疑其中一些规则可能是使用一个或多个约束函数实现的,但到目前为止我能够找到的所有示例都非常简单,并没有多大帮助。

感谢您提供的任何提示。

-- Cleanup 
DROP TABLE #lkupMasterFieldList    

0 个答案:

没有答案