### SQL 触发器知识点详解
#### 一、利用 `INSTEAD OF` 触发器实现工资的自动计算
**知识点概述:**
在SQL Server中,触发器是一种特殊的存储过程,它会在特定的数据库操作(如INSERT、UPDATE或DELETE)执行前后自动执行。`INSTEAD OF`触发器是一种特殊类型的触发器,当触发器被激活时,它会代替原本的操作,并执行触发器中的定义逻辑。
**具体实现:**
根据提供的部分代码,我们可以看到如何创建一个用于自动计算税后工资的触发器。
1. **创建表**:首先创建了一个名为“工资表”的表,包含以下字段:
- 员工号:整型,自动增长。
- 工资:货币类型。
- 扣税利率:数值类型,长度为2位,小数点后1位。
- 税后工资:货币类型。
2. **修改表结构**:通过`ALTER TABLE`命令修改了“扣税利率”字段的精度。
3. **创建触发器**:使用`CREATE TRIGGER`命令创建了一个名为“计算工资”的触发器,该触发器在执行插入操作时被激活,并且其行为是代替原本的插入操作(`INSTEAD OF INSERT`)。
4. **触发器逻辑**:触发器内部首先声明了两个变量,分别为`@工资`和`@扣税比例`,并从插入操作中获取对应的值。接着,根据工资和扣税比例计算税后工资,并将结果插入到“工资表”中。
**示例代码:**
```sql
GO
CREATE TRIGGER 计算工资
ON 工资表
INSTEAD OF INSERT AS
BEGIN
DECLARE @工资 MONEY,
@扣税比例 NUMERIC(2, 1);
SELECT @工资 = 工资,
@扣税比例 = 扣税利率
FROM inserted;
INSERT INTO 工资表 (工资, 扣税利率, 税后工资)
VALUES (@工资, @扣税比例, @工资 * (1 - @扣税比例));
END
GO
```
#### 二、利用 `INSTEAD OF` 实现基于多个表的视图更新
**知识点概述:**
`INSTEAD OF` 触发器也可以用于基于多个表的视图更新。当试图更新视图时,如果视图基于多个基表,则通常需要编写复杂的逻辑来确保更新的一致性和完整性。
**具体实现:**
1. **创建视图**:创建了一个名为`studentinfo_view`的视图,该视图基于`student`和`sc`两个表。
2. **创建触发器**:创建了一个名为“更新学生的信息”的触发器,该触发器在对`studentinfo_view`视图执行插入操作时被激活。
3. **触发器逻辑**:触发器内部获取了插入操作涉及的所有字段值,并将其插入到视图中。但实际上,由于视图是由多个基表组成的,因此这里的插入操作实际上是无效的,因为视图本身不支持直接插入操作。
**示例代码:**
```sql
GO
CREATE VIEW studentinfo_view
AS
SELECT student.sno, student.sbirth, student.sname, student.sdept, sc.grade
FROM student JOIN sc ON student.sno = sc.sno;
GO
CREATE TRIGGER 更新学生的信息
ON studentinfo_view
INSTEAD OF INSERT AS
BEGIN
DECLARE @学生号 CHAR(10),
@出生日期 SMALLDATETIME,
@名字 NVARCHAR(4),
@系部 NVARCHAR(25),
@成绩 TINYINT;
SELECT @学生号 = sno,
@出生日期 = sbirth,
@名字 = sname,
@系部 = sdept,
@成绩 = grade
FROM inserted;
INSERT INTO studentinfo_view (sno, sbirth, sname, sdept, grade)
VALUES (@学生号, @出生日期, @名字, @系部, @成绩);
END
GO
```
#### 三、创建服务器级别的触发器
**知识点概述:**
除了在数据库级别创建触发器之外,还可以在服务器级别创建触发器。服务器级别的触发器可以在任何数据库上触发。
**具体实现:**
1. **无权创建登录名触发器**:创建了一个名为`no_right_login`的触发器,该触发器在所有服务器上对`CREATE_LOGIN`事件生效。触发器内部打印一条消息表示无法建立账户。
2. **限制对数据库的操作触发器**:创建了一个名为`no_right_database`的触发器,该触发器在所有服务器上对`DROP_DATABASE`、`ALTER_DATABASE`和`CREATE_DATABASE`事件生效。触发器内部打印一条消息表示不允许修改、删除或创建数据库,并回滚当前事务。
3. **限制对表的操作触发器**:创建了一个名为`no_right_table`的触发器,该触发器在当前数据库上对`DROP_TABLE`、`CREATE_TABLE`和`ALTER_TABLE`事件生效。触发器内部打印一条消息表示不允许修改、删除或创建表,并回滚当前事务。
**示例代码:**
```sql
GO
CREATE TRIGGER no_right_login
ON ALL SERVER
FOR CREATE_LOGIN
AS
PRINT '无法建立账户!';
GO
GO
CREATE TRIGGER no_right_database
ON ALL SERVER
FOR DROP_DATABASE, ALTER_DATABASE, CREATE_DATABASE
AS
BEGIN
PRINT '不能修改库,删除库,创建库';
ROLLBACK TRANSACTION;
END
GO
GO
CREATE TRIGGER no_right_table
ON DATABASE -- 默认为当前的数据库库
FOR DROP_TABLE, CREATE_TABLE, ALTER_TABLE
AS
BEGIN
PRINT '不可以修改表,建立表,删除表';
ROLLBACK TRANSACTION;
END
GO
```
以上示例展示了如何利用SQL Server中的`INSTEAD OF`触发器实现特定的功能,以及如何在不同级别创建触发器以限制某些操作。通过这些示例,我们可以更好地理解触发器的工作原理及其在实际应用中的作用。