这是一个系列,需几个文档一起看
--实验7.1存储过程
--(1)使用Employees中员工人数来初始化一个局部变量,并调用这个存储过程
Create PROCEDURE test @number1 int output --输出参数,可以从程序中返回信息
As
begin
Declare @number2 int
Set @number2=(Select COUNT(*) from Employees)
Set @number1=@number2
end
--调用
Declare @num int
EXEC test @num output
Select @num
--(2)比较两个员工的实际收入,若前者高则输出0,若后者高则输出1
Create PROCEDURE compa @id1 char(6),@id2 char(6),@bj int output
as
Begin
Declare @sr1 float, @sr2 float
Select @sr1=income-outcome from salary Where EmployeeID=@id1
Select @sr2=income-outcome from salary Where EmployeeID=@id2
If @sr1>@sr2
Set @bj=0
Else
Set @bj=1
end
--调用
Declare @bj int
EXECUTE compa '000001','108991',@bj output
Select @bj
--(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
--调用
EXEC EmployeeAdd '990230','文松','本科','840909',2,1,'重庆武隆','85465213','3'
--(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时将其转移到经理办公室工作
Select * from dbo.Departments
Select * from dbo.Employees
Select * from dbo.Salary
Create PROCEDURE que1 @id char(6)
as
Begin
Declare @workyear char(6),@dep_id char(3)
Select @workyear=workyear from Employees Where EmployeeID=@id
Select @dep_id=Departments.departmentID from employees,departments
Where employees.DepartmentID=departments.DepartmentID
and departmentName='经理办公室'
If @workyear>6
Update Employees Set departmentID=@dep_id Where EmployeeID=@id
end
--调用
EXEC que1 '000001'
--根据每个员工的学历将收入提高500
Create Procedure que2 @id char(6)
As
Begin
Declare @education char(6)
Select @education=Education from Employees Where EmployeeID=@id
Update salary Set Income=income+500 Where EmployeeID=@id
end
--执行
EXEC que2 '000001'
--使用游标计算本科及以上学历的员工在员工总数中占的比例
Declare @edu varchar(10),@part_count int,@all_count int
Declare mycursor cursor
for Select distinct education,count(education) over(partition by education)as part_count,
count(education) over() as all_count from Employees
open mycursor
fetch next from mycursor into @edu,@part_count,@all_count
While @@FETCH_STATUS=0
Begin
print @edu+'占总人数比例:'+convert(varchar(100),convert(numeric(38,2),@part_count/1.0/@all_count*100)+'%'
fetch next from mycursor into @edu,@part_count,@all_count
end
close mycursor
deallocate mycorsor
--实验7.2 触发器
--(1)向Employees表插入一个记录时,通过触发器检查记录的DepartmentID在Departments中是否存在,不存在则取消插入或修改操作
Create Trigger employeesIns on dbo.Employees
for insert,Update
as
Begin
IF((Select DepartmentID from inserted)not in
(Select DepartmentID from Departments))
Rollback --恢复到插入前的状态
end
--(2)修改Departments的DepartmentID字段时,该字段在Employees中的对应之也做相应修改
Create Trigger DepartmentsUpdate on dbo.Departments
for Update
As
Begin
Update Employees
Set DepartmentID=(Select DepartmentID from inserted)
Where DepartmentID=(Select DepartmentID from deleted)
End
--(4)删除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中是否存在,
--如果存在则执行插入操作,如果不存在则提示“员工编号不存在”
Create Trigger EM_EXISTS on salary
Instead of Insert
as
Begin
Declare @employeeID char(6)
Select @employeeID=EmployeeID from inserted
If (@employeeID in (Select EmployeeID from Employees))
Insert into salary Select * from inserted
Else
print '员工编号不存在'
end
--(5)创建DDL触发器,当删除YGGL的一个表时,提示‘不能删除表’,并回滚删除表的操作
Create Trigger table_delete on Database
After drop_table
as
print '不能删除表'
rollback transaction
--Employees与salary的EmployeeID应满足完整性规则,请用触发器实现两个表之间的参照完整性
Create Trigger que1_1 on salary
for insert,update
as
Begin
If(Select employeeid from inserted)not in
(Select EmployeeID from Employees)
rollback
end
Create trigger que1_2 on Employees
for update
as
Begin
Update Salary Set zemployeeID=(Select Employeeid from inserted)
Where EmployeeID=(Select employeeid from deleted)
end
Create Trigger que1_3 on Employees
for delete
as
Begin
Delete from salary
Where EmployeeID=(Select EmployeeID from deleted)
End
--若将Employees中员工的工作时间增加到1年,则收入增加500,若增加两年则增加1000
Create Trigger que2_1 on Employees
After update
as
Begin
Declare @a int,@b int
Set @a=(Select workyear from inserted)
Set @b=(Select workyear from deleted)
If (@a>@b)
update salary
Set income=income+(@a-@b)*500
Where EmployeeID in (Select EmployeeID from inserted)
End
--创建UPdate触发器,当salary中income增加500时,outcome增加50
Create Trigger que3_1 on salary
for update
as
Begin
If((Select income from inserted)-(Select income from deleted)=500)
Update salary Set outcome=outcome+50
Where EmployeeID=(Select EmployeeId from inserted)
end
--创建instead of触发器,实现向不可更新视图插入数据
Create VIEW a_view
as
Select a.EmployeeID,name,workyear,income,outcome from Employees a,salary b
Where Employees.employeeID=Salary.EmployeeID
Create Trigger que4_1 on a_view
Instead of insert
as
Begin
Declare @ei char(6),@name char(10),@wy tinyint,@ic float,@oc float
Select @ei=EmployeeID,@name=name,@wy=workyear,@ic=income,@oc=outcome
from inserted
insert into Employees(EmployeeID,name,workyear)values(@ei,@name,@wy)
insert into salary values(@ei,@ic,@oc)
end
--创建DDl触发器,当删除数据库时,提示无法删除,并回滚删除操作
Create Trigger que5_1 on all server
after drop_database
as
print '不能删除'
rollback transaction
drop database YGGL