存储过程
(1)创建存储过程,使用Employees表中的员工人数来初始化一个局部变量,并调用这个存储过程。
1. Create PROCEDURE test @number1 int output --输出参数,可以从程序中返回信息
2. As
3. begin
4. Declare @number2 int
5. Set @number2=(Select COUNT(*) from Employees)
6. Set @number1=@number2
7. end
运行结果如下
执行该存储过程,并查看结果。
Declare @num int
EXEC test @num output
Select @num
运行结果如下
(2)创建存储过程,比较两个员工的实际收入,若前者比后者高就输出0,否则输出1。
1. Create PROCEDURE compa @id1 char(6),@id2 char(6),@bj int output
2. as
3. Begin
4. Declare @sr1 float, @sr2 float
5. Select @sr1=income-outcome from salary Where EmployeeID=@id1
6. Select @sr2=income-outcome from salary Where EmployeeID=@id2
7. If @sr1>@sr2
8. Set @bj=0
9. Else
10. Set @bj=1
11. end
12. GO
运行结果如下
(3)创建添加职员记录的存储过程EmployeeAdd。
Create PROCEDURE EmployeeAdd
(
@employeeid char(6),@name char(10),@education char(4), @birthday datetime,
@workyear tinyint,@sex bit,@address char(40), @phonenumber char(12),
@departmentID char(3))
As
Begin
Insert into employees
values(@employeeid,@name,@education,@birthday,@workyear,
@sex,@address,@phonenumber,@departmentID)
end
return
运行结果如下
(4)创建带output游标参数的存储过程,在employees中声明并打开一个游标。
Create PROCEDURE em_cursor @em_cursor cursor VARYING output
As
Begin Set @em_curcor=CURSOR forward_only static FOR Select * from Employees open @em_cursor
end
运行结果如下
声明一个局部游标变量,执行上述存储过程,并将游标赋值给局部游标变量,然后通过该游标变量读取记录
Declare @mycursor cursor
EXEC em_cursor @em_cursor=@mycursor output
Fetch next from @mycursor
While(@@FETCH_STATUS=0)
begin fetch next from @mycursor
end
close @mycursor
deallocate @mycursor
运行结果如下
(5)创建存储过程,使用游标确定一个员工的实际收入是否排在前三名。结果为1表示是,结果为0表示否。
Create PROCEDURE top_three @em_id char(6),@ok bit output
As
Begin Declare @x_em_id char(6) Declare @act_in int,@seq int Declare salary_ids cursor for Select EmployeeID,Income-Outcome from salary order by income-outcome desc Set @seq=0 Set @ok=0 open salary_ids fetch salary_ids into @x_em_id,@act_in While @seq<3 and @ok=0 begin Set @seq=@seq+1 if @x_em_id=@em_id Set @ok=1 fetch salary_ids into @x_em_id,@act_in end close salary_ids deallocate salary_ids
end
运行结果如下
执行该存储过程
Declare @ok bit
EXEC top_three '108991',@ok output
Select @ok
运行结果如下
要求一个员工的工作年份大于6时将其转移到经理办公室工作
1. Select * from dbo.Departments
2. Select * from dbo.Employees
3. Select * from dbo.Salary
4.
5. Create PROCEDURE que1 @id char(6)
6. as
7. Begin
8. Declare @workyear char(6),@dep_id char(3)
9. Select @workyear=workyear from Employees Where EmployeeID=@id
10. Select @dep_id=Departments.departmentID from employees,departments
11. Where employees.DepartmentID=departments.DepartmentID
12. and departmentName='经理办公室'
13. If @workyear>6
14. Update Employees Set departmentID=@dep_id Where EmployeeID=@id
15. end
根据每个员工的学历将收入提高500
1. Create Procedure que2 @id char(6)
2. As
3. Begin
4. Declare @education char(6)
5. Select @education=Education from Employees Where EmployeeID=@id
6. Update salary Set Income=income+500 Where EmployeeID=@id
7. end
使用游标计算本科及以上学历的员工在员工总数中占的比例
1. Declare @edu varchar(10),@part_count int,@all_count int
2. Declare mycursor cursor
3. for Select distinct education,count(education) over(partition by education)as part_count,
4. count(education) over() as all_count from Employees
5. open mycursor
6. fetch next from mycursor into @edu,@part_count,@all_count
7. While @@FETCH_STATUS=0
8. Begin
9. print @edu+'占总人数比例:'+convert(varchar(100),convert(numeric(38,2),@part_count/1.0/@all_count*100)+'%'
10. fetch next from mycursor into @edu,@part_count,@all_count
11. end
12. close mycursor
13. deallocate mycorsor
触发器
对于TGGL数据库,Employees表的DepartmentID列与Departments表的DepartmentID列应满足参照完整性规则。
- 向Employees表添加记录时,该记录的DepartmentID字段值在Departments表中应存在。
- 修改Departments表的DepartmentID字段值时,该字段在Employees表中的对应值也应修改。
- 删除Departments表的记录时,该记录的DepartmentID字段值在Employees表中对应的记录也应删除。
对于上述参照完整性规则,在此通过触发器实现。
(1)向Employees表插入一个记录时,通过触发器检查记录的DepartmentID在Departments中是否存在,不存在则取消插入或修改操作。
1. Create Trigger employeesIns on dbo.Employees
2. for insert,Update
3. as
4. Begin
5. IF((Select DepartmentID from inserted)not in
6. (Select DepartmentID from Departments))
7. Rollback
8. end
运行结果如下
(3)删除Departments中记录的同时删除Employees中DepartmentID对应记录.
Create Trigger DepartmentDelete on dbo.Departments for Delete as Begin Delete from Employees Where DepartmentID=(Select DepartmentID from deleted) end
运行结果如下
(4)创建Instead of触发器,当向salary中插入记录时,先检查EmployeeID列上的值在Employees中是否存在,如果存在则执行插入操作,如果不存在则提示“员工编号不存在”。
1. Create Trigger EM_EXISTS on salary
2. Instead of Insert
3. as
4. Begin
5. Declare @employeeID char(6)
6. Select @employeeID=EmployeeID from inserted
7. If (@employeeID in (Select EmployeeID from Employees))
8. Insert into salary Select * from inserted
9. Else
10. print '员工编号不存在'
11. end
运行结果如下
(5)创建DDL触发器,当删除数据库的一个表时,提示‘不能删除表’,并回滚删除表的操作。
Create Trigger table_delete on Database
After drop_table
as print '不能删除表' rollback transaction
运行结果如下
Employees与salary的EmployeeID应满足完整性规则,请用触发器实现两个表之间的参照完整性。
1. Create Trigger que1_1 on salary
2. for insert,update
3. as
4. Begin
5. If(Select employeeid from inserted)not in
6. (Select EmployeeID from Employees)
7. rollback
8. end
9. Create trigger que1_2 on Employees
10. for update
11. as
12. Begin
13. Update Salary Set zemployeeID=(Select Employeeid from inserted)
14. Where EmployeeID=(Select employeeid from deleted)
15. end
16.
17. Create Trigger que1_3 on Employees
18. for delete
19. as
20. Begin
21. Delete from salary
22. Where EmployeeID=(Select EmployeeID from deleted)
23. End
若将Employees中员工的工作时间增加到1年,则收入增加500,若增加两年则增加1000。
1. Create Trigger que2_1 on Employees
2. After update
3. as
4. Begin
5. Declare @a int,@b int
6. Set @a=(Select workyear from inserted)
7. Set @b=(Select workyear from deleted)
8. If (@a>@b)
9. update salary
10. Set income=income+(@a-@b)*500
11. Where EmployeeID in (Select EmployeeID from inserted)
12. End
创建UPdate触发器,当salary中income增加500时,outcome增加50。
1. Create Trigger que3_1 on salary
2. for update
3. as
4. Begin
5. If((Select income from inserted)-(Select income from deleted)=500)
6. Update salary Set outcome=outcome+50
7. Where EmployeeID=(Select EmployeeId from inserted)
8. end
创建instead of触发器,实现向不可更新视图插入数据。
1. Create VIEW a_view
2. as
3. Select a.EmployeeID,name,workyear,income,outcome from Employees a,salary b
4. Where Employees.employeeID=Salary.EmployeeID
5. Create Trigger que4_1 on a_view
6. Instead of insert
7. as
8. Begin
9. Declare @ei char(6),@name char(10),@wy tinyint,@ic float,@oc float
10. Select @ei=EmployeeID,@name=name,@wy=workyear,@ic=income,@oc=outcome
11. from inserted
12. insert into Employees(EmployeeID,name,workyear)values(@ei,@name,@wy)
13. insert into salary values(@ei,@ic,@oc)
14. end
创建DDl触发器,当删除数据库时,提示无法删除,并回滚删除操作。
1. Create Trigger que5_1 on all server
2. after drop_database
3. as
4. print '不能删除'
5. rollback transaction
6. drop database Hao