Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 排除某些单词的触发器_Sql_Sql Server_Tsql_Database Trigger_Check Constraints - Fatal编程技术网

Sql 排除某些单词的触发器

Sql 排除某些单词的触发器,sql,sql-server,tsql,database-trigger,check-constraints,Sql,Sql Server,Tsql,Database Trigger,Check Constraints,我有一个关于T-SQL中数据库触发器的问题 我想创建一个触发器,它只允许特定的字可用,而不允许列可用 如何做到这一点 我知道触发器是什么,但在命令序列中丢失了什么-什么之后应该是什么。不确定这里是否真的需要触发器。另一种解决方案是在相关列上创建检查约束,如: ALTER TABLE TableName ADD CONSTRAINT availability_check CHECK (availability IN ('available', 'not available')); : 解决这个问

我有一个关于T-SQL中数据库触发器的问题

我想创建一个触发器,它只允许特定的字可用,而不允许列可用

如何做到这一点


我知道触发器是什么,但在命令序列中丢失了什么-什么之后应该是什么。

不确定这里是否真的需要触发器。另一种解决方案是在相关列上创建检查约束,如:

ALTER TABLE TableName
ADD CONSTRAINT availability_check CHECK (availability IN ('available', 'not available'));
:


解决这个问题有两种方法

选择:基于检查约束的方法:只需使用检查约束即可实现。正如@GMB在他的回答中已经提到的那样,这使工作更简单。 更改表1添加约束CHK\U表1\U可用性检查“可用”、“不可用”中的可用性 不要使用:基于触发器的方法:如果您想创建触发器,可以创建替代触发器,如下所示。此外,您还应该创建类似的而不是更新触发器,以处理更新场景。但是,这是一种迂回的方法。请参阅所需代码的数量,以及相应的维护。 创建触发器[dbo]。[tr\U可用性\U插入] 关于[dbo]。[表1] 而不是插入 像 开始 开始尝试 开始交易 不计数; 如果插入。可用性在“可用”、“不可用”中 开始 在表1ID中插入可用性 选择Id,从中选择可用性 终止 犯罪 结束尝试 开始捕捉 如果@TRANCOUNT>0 回降 回来 端接 创建触发器[dbo]。[tr\U可用性\U更新] 关于[dbo]。[表1] 而不是更新 像 开始 开始尝试 开始交易 不计数; 如果插入。可用性在“可用”、“不可用”中 开始 更新表1 设置可用性=已插入。可用性 其中Table1.Id=插入的.Id; 终止 犯罪 结束尝试 开始捕捉 如果@TRANCOUNT>0 回降 回来 端接 您可以根据需要直接更改表并添加检查约束

ALTER TABLE YourTableName
ADD CONSTRAINT CHK_Avalability CHECK(Avalability IN('Available', 'Not Available'));
请注意,如果表中已经插入了一些数据,并且与CHECK约束不匹配或冲突,则这将引发错误

如果您还没有创建表,那么可以使用

CREATE TABLE YourTableName(
  Availability VARCHAR(20) NOT NULL
    CONSTRAINT CHK_Avalability CHECK(Availability IN('Available', 'Not Available')) 
);

我会选择支票约束。另一种方法是使用引用约束,即主键和外键。如果在多个位置使用“可用”和“不可用”,这将比检查约束更好,因为您可以跨多个表强制执行相同的规则。通过这种方式,您可以强制执行一致性,并避免某些表具有其他值,如available和unavailable

-- Lookup table for all possible "Availability" values
CREATE TABLE dbo.LU_Availability
(
  AvailabilityPK VARCHAR(14) NOT NULL,
  CONSTRAINT pk_LU_Availability PRIMARY KEY CLUSTERED(AvailabilityPK)
);
INSERT dbo.LU_Availability (AvailabilityPK) VALUES ('Available'),('Not Available');

-- Table with the allowable values enforced via foriegn key constraint
CREATE TABLE dbo.YourTable
(
  someId         INT IDENTITY,
  someValue      CHAR(10),
  [Availability] VARCHAR(14) NOT NULL,
  CONSTRAINT fk_AvailabilityTxt FOREIGN KEY([Availability]) 
    REFERENCES dbo.LU_Availability(AvailabilityPK)
);

INSERT dbo.YourTable ([Availability]) VALUES ('Available');     -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('NOT Available'); -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('Perhaps');       -- Fails

最后,重要的是要理解,虽然约束检查、PK、FK、UNIQUE会让事情慢一点,但触发器是性能杀手。这就是为什么有经验的开发人员和DBA建议在有约束的情况下避免使用它们

不确定是否确实需要触发器的可能重复项,为什么不在相关列上创建检查约束?需要插入前触发器。有很多通过护目镜的例子。或者是@GMB的建议。这听起来绝对像是你在描述检查约束,而不是触发器。触发器对于这项工作来说绝对是错误的工具。使用检查约束。可以使用触发器,但是:1。当用户试图更新列时,您必须编写类似的代码。2.您必须为触发器内表中的所有列提供insert/update语句。这不是一个可怕的问题,但它使数据库的维护变得更加困难。@ZoharPeled,同意你的看法。我只是提供了代码,以便他能够理解所涉及的工作量。我还提到,他必须再次编写而不是更新触发器。我自己建议只检查约束。@ZoharPeled,我已经更新了我的答案,以澄清插入所需的工作量。“可用”、“不可用”中的可用性有不平衡的括号,不清楚它如何检查插入的所有行。UPDATE Table1Availability SET Availability=inserted。Availability在如何从inserted中选择数据方面也有点神秘,但至少它更新了表中的所有行,因为没有where子句。@HABO,感谢您发现这个问题。纠正了他们。我只想提到这项工作的复杂性。OP未提供表架构和全部。刚才提到了努力。
-- Lookup table for all possible "Availability" values
CREATE TABLE dbo.LU_Availability
(
  AvailabilityPK VARCHAR(14) NOT NULL,
  CONSTRAINT pk_LU_Availability PRIMARY KEY CLUSTERED(AvailabilityPK)
);
INSERT dbo.LU_Availability (AvailabilityPK) VALUES ('Available'),('Not Available');

-- Table with the allowable values enforced via foriegn key constraint
CREATE TABLE dbo.YourTable
(
  someId         INT IDENTITY,
  someValue      CHAR(10),
  [Availability] VARCHAR(14) NOT NULL,
  CONSTRAINT fk_AvailabilityTxt FOREIGN KEY([Availability]) 
    REFERENCES dbo.LU_Availability(AvailabilityPK)
);

INSERT dbo.YourTable ([Availability]) VALUES ('Available');     -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('NOT Available'); -- Succeeds
INSERT dbo.YourTable ([Availability]) VALUES ('Perhaps');       -- Fails