SQL視圖、存儲過程、觸發器、遊標及完整性

實驗之前最好重新建一個數據庫,記得改路徑
這個可以查SQL的基本語句https://www.runoob.com/sql/sql-tutorial.html

USE [master]
GO

/****** Object:  Database [xscj]    Script Date: 2020/2/21 16:42:38 ******/
CREATE DATABASE [xscj]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'XSCJ_Data', FILENAME = N'home\learn\xscj.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
 LOG ON 
( NAME = N'XSCJ_Log', FILENAME = N'home\learn\xscj_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

USE [xscj]
GO
/****** Object:  Table [dbo].[COU]    Script Date: 2020/2/21 16:42:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

DROP TABLE SC
GO
DROP TABLE COU
GO
DROP TABLE STU
GO
DROP TABLE MAJOR
GO


CREATE TABLE dbo.COU(
	CNO char(4) NOT NULL,
	CNAME varchar(30) NOT NULL,
	CREDIT smallint NULL,
	PTIME char(5) NULL,
	TEACHER nchar(10) NULL,
 CONSTRAINT PK_COU PRIMARY KEY CLUSTERED 
(
	CNO ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON PRIMARY
GO
/****** Object:  Table [dbo].[MAJOR]    Script Date: 2020/2/21 16:42:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE major(
	mno char(2) NOT NULL,
	mname varchar(20) NOT NULL,
 CONSTRAINT PK_MAJOR PRIMARY KEY CLUSTERED 
(
	mno ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON PRIMARY
GO
/****** Object:  Table [dbo].[SC]    Script Date: 2020/2/21 16:42:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE sc(
	sno char(4) NOT NULL,
	cno char(4) NOT NULL,
	grade numeric(6, 1) NULL,
 CONSTRAINT [PK_SC] PRIMARY KEY CLUSTERED 
(
	[SNO] ASC,
	[CNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[STU]    Script Date: 2020/2/21 16:42:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE stu(
	sno char(4) NOT NULL,
	sname char(8) NOT NULL,
	sex int NULL,
	mno char(2) NULL,
	birdate smalldatetime NULL,
	memo text NULL,
 CONSTRAINT [PK_STU] PRIMARY KEY CLUSTERED 
(
	[SNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE stu   ALTER COLUMN sex SET DEFAULT 1;

GO
ALTER TABLE sc WITH NOCHECK ADD  CONSTRAINT FK_CNO FOREIGN KEY(cno)
REFERENCES cou (cno)
GO
ALTER TABLE [dbo].[SC] CHECK CONSTRAINT [FK_CNO]
GO
ALTER TABLE cou  ADD   CHECK  ((credit>=0 AND credit<=20))
GO
ALTER TABLE [dbo].[COU] CHECK CONSTRAINT [ck_credit]
GO
USE [master]
GO
ALTER DATABASE [xscj] SET  READ_WRITE 
GO

USE xscj
GO

insert cou  values ( 'C001','高等數學',8,'1','孫老師');
insert cou values ( 'C002','C語言',5,'2','張老師');
insert cou values ( 'C003','數據結構',4,'3','張老師');
insert cou  values ( 'C004','操作系統',3,'4','羅老師');
insert cou values ( 'C005','組成原理',4,'3','陳老師');
insert cou  values ( 'C006','數據庫原理',3,'5','吳老師');
insert cou  values ( 'C007','JAVA程序設計',3,'3','李老師');


insert major values ( '01','計算機工程');
insert major  values ( '02','軟件工程');
insert major  values ( '03','網絡工程');
insert major  values ( '04','智能技術');

insert stu  values ( 'S001','張三',1,'01','2001-10-01 00:00:00.000','二年級,榮獲學院三好學生');
insert stu  values ( 'S002','李四 ',0,'02','2001-05-13 00:00:00.000',NULL);
insert stu  values ( 'S003','李芳  ',0,'01','2000-05-11 00:00:00.000',NULL);
insert stu  values ( 'S004','張明 ',1,'02','2002-05-31 00:00:00.000','一年級,榮獲優秀學生幹部');
insert stu  values ( 'S005','張強  ',1,'02','2001-06-01 00:00:00.000',NULL);
insert stu  values ( 'S006','吳玲 ',0,'02','2000-06-11 00:00:00.000',NULL);
insert stu  values ( 'S007','鄭奇 ',1,'01','2000-06-11 00:00:00.000',NULL);
insert stu  values ( 'S008','吳麗麗',0,'03','2001-06-17 00:00:00.000',NULL);
insert stu  values ( 'S009','林森 ',1,'03','2002-01-10 00:00:00.000',NULL);
insert stu  values ( 'S010','徐小宜 ',1,'04','2003-05-11 00:00:00.000',NULL);

insert sc  values ( 'S001','C001',68.6);
insert sc  values ( 'S001','C002',95.5);
insert sc  values ( 'S001','C003',74.5);
insert sc  values ( 'S002','C001',70.0);
insert sc  values ( 'S002','C002',86.1);
insert sc  values ( 'S003','C001',89.3);
insert sc  values ( 'S003','C005',78.8);
insert sc  values ( 'S003','C006',67.6);
insert sc  values ( 'S004','C002',67.6);
insert sc  values ( 'S004','C004',50.2);
insert sc  values ( 'S005','C002',80.9);
insert sc  values ( 'S010','C001',NULL);


select * from sc
select * from cou
select * from stu
select * from major



1.視圖的創建與應用
基本概念
爲表 sc創建一個視圖,包括有各個學生學號、選修課程的門數及平均分,如:
create view s_grade(sno,c_num,avg_grade)
as
select sno,count(cno),avg(grade) from sc group by sno

實踐下列查詢和更新操作的功能,是否出錯,若可運行,寫出轉換至基本表SC上的相應操作。 若不可運行,說明原因
(1)select * fr
(2)om s_grade;

(3)select sno,c_num from s_grade where avg_grade>80

(4)select sno,avg_grade from s_grade where c_num>(select c_num from s_grade where sno=’S004’)

(5)update s_grade set c_num=c_num+2

(5)delete from s_grade where c_num>3

2.對SC表創建視圖COMPUTER_SC,該視圖包括‘01’專業的學生的學號、姓名與性別
設計實驗完成該視圖數據的查詢、添加、修改與刪除。進一步理解行列子集視圖與非行列子集視圖應用上的區別

create view  COMPUTER_SC 
as select sno, sname, sex from stu where mno = '01'

select * from COMPUTER_SC;
insert into COMPUTER_SC values('S012', '葉華', '1')

update COMPUTER_SC set sname = '花生醬' where sno = 'S001'


delete from COMPUTER_SC where sno = 'S001'

3.T-SQL
1)使用CASE WHEN

查詢學生的所有信息,若性別爲1,則性別顯示‘男’,否則顯示‘女’

select * , '性別' = case when sex = 1 then '男' else '女' end from stu

2)使用WHILE及遊標等
遊標概念用法請戳
對SC表添加一個等級列,若學生成績80及以上等級A,70-79分爲B,其餘爲C,null仍爲null


declare @sno char(4),@cno char(4),@grade numeric(6, 1),@rank char(1)
declare sc_cur1 cursor
	for
		select *
		from sc
open sc_cur1
while(@@fetch_status=0)
begin
	fetch next from sc_cur into @sno,@cno,@grade
	if(@grade>=80) set @rank='A'
	else if(@grade>=70 and @grade<70) set @rank='B'
	else if(@grade is null) set @rank=null
	else set @rank='C'
	select sno=@sno,cno=@cno,grade=@grade,rank=@rank
end
close sc_cur1
deallocate sc_cur1

3)使用WHILE及遊標
在XSCJ數據庫運行如下腳本,
Create table sumcredit(sno char(4) primary key,sum_credit numeric(4,1))
Insert into sumcredit select sno,0 from stu
使用遊標完成每個學生的總學分,並更新入sumcredit表中。只有60分及以上纔可獲得課程學分。


deallocate sum_cur
declare @sno char(4), @sum numeric(4,1)
declare sum_cur cursor for 
select sno, sum(credit) from sc left outer join cou on sc.cno = cou.cno and  sc.grade >=60 group by sc.sno
open sum_cur
fetch next from sum_cur into @sno, @sum
while(@@FETCH_STATUS = 0)
begin
	fetch next from sum_cur into @sno, @sum 
	update sumcredit set sum_credit = @sum where sumcredit.sno = @sno
end
close sum_cur
select * from sumcredit

4.據SQL SERVER提供的完整性完成完整性實踐
SQL SERVER提供的數據庫完整性包括域完整性(CHECK,DEFAULT,UNQUE,RULE,用戶自定義類型、基本數據類型)、表間完整性(複習實體完整性、參照完整性的定義與驗證)、複雜完整性表達(觸發器)
1)創建stu1,major1表,表的結構與xscj數據庫的的stu及major一致。在創建與修改表結構的過程中應用好以上完整性概念
2)插入數據,說明實體完整性與參照完整性的檢查機制。刪除數據說明參照完整性的檢查機制。截圖說明

3)對STU1表任意插入一條數據,該數據違背了你所定義的所有完整性規則。分別說明 違背了什麼,並截圖

完整性概念

2)創建一個用戶自定義類型,用於定義MAJOR1表與STU1表的mno(提示:查看幫助CREATE TYPE 、CREATE RULE,SP_BINDRULE,SP_UNBINDRULE等) 專業號由M開頭,其餘字符爲數字字符,長度爲2.

sno like ‘S[0-9][0-9]

5、存儲過程創建與使用
1)創建存儲過程P1,查詢學生表所有信息;運行之。

create procedure p1 as select * from stu
p1

2)創建存儲過程P2,查詢某學號學生的所有信息,運行

create procedure p2 @sno char(4) as select * from stu where sno = @sno
p2 'S001';


3)創建存儲過程P3,查詢某學號學生的姓名及所就讀專業,運行之

create procedure p3 @sno char(4) as select sname, mname from stu, major where sno = @sno and stu.mno = major.mno

p3 'S001';

4)創建存儲過程P4,查詢某課程名的平均分,選課人數並輸出之。運行之


create procedure p4 @cname varchar(30) as select cname, avg(grade) from sc, cou 
where sc.CNO = cou.cno and cname = @cname group by cname

p4 '高等數學'

5)創建存儲過程P5,完成該生的退學業務處理(即刪除某學號學生的所有信息),運行之。

create procedure p5 @sno char(4) as
delete sc from sc where sno = @sno
delete stu from stu where sno = @sno

p5 'S013'

6)創建存儲過程P6,完成爲某學號學生插入兩條選課記錄(注意不能插入重複的選課記錄),並返回統計當前選修了幾門課。運行之


create procedure p6 @sno char(4) as
insert into sc values(@sno, 'C004', 99)
insert into sc values(@sno, 'C005', 66)
select count(cno) as sumcno from sc where sno = @sno group by sno
p6 'S009'
--drop procedure p6

7)創建存儲過程P7,返回每個學生的平均分。運行之

create procedure p7 as
select sno, avg(grade) from sc group by sno

p7

8)創建存儲過程P8,完成學生狀態處理,若學生75分以下課程數超過其75分以上的課程數,則留級,否則標註爲升學,運行之
提示:存儲過程創建可參考CREATE PROCEDURE的幫助。

create procedure p8 as
select distinct sno, sname, '狀態' = case when
(select count(grade) from sc where grade >= 60 and sno = stu.sno) 
>=
(select count(grade) from sc where grade < 60 and sno = stu.sno)
then '正常' 
else '留級'
end
from stu
p8

6.觸發器應用
觸發器(create trigger)
1)創建觸發器
,實現對SC表插入一條記錄,若該選課記錄存在則提示插入錯,否則插入該記錄。用插入成功與插入失敗的兩個截圖說明觸發器如何工作。
觸發器是一種特殊的存儲過程,它不能被顯式地調用,而是在往表中插入記錄﹑更新記錄或者刪除記錄時被自動地激活。 所以觸發器可以用來實現對錶實施複雜的完整性約束。
觸發器基礎知識

觸發器用法

create trigger cr_sc on sc after insert as 
begin tran tran_sc
declare @sno varchar(4)
declare @cno varchar(4)
declare @cnt int
set @sno = (select sno from inserted)
set @cno = (select cno from inserted)
set @cnt = (select count(cno) from sc where sno = @sno and cno = @cno group by sno)
if(@cnt >= 2)
begin 
print '已存在該選課'
rollback tran
end
else begin
print '選課成功'
commit tran
end

2)創建觸發器,實現每門課最多隻能8個學生選修。


create trigger tri_sc on sc
after insert 
as 
begin tran p_num
declare @cno varchar(4)
declare @cnt int
set @cnt = (select count(sno) from sc where cno = @cno)
if(@cnt >= 8)
begin
print '選課人數已達上限,請選擇其他課程'
rollback tran
end
else begin 
print '選課成功'
commit tran 
end

3)創建觸發器,實現每個學生最多選修5門課.

create trigger t_sc on sc 
after insert 
as
begin tran p_num
declare @sno varchar(4) 
declare @cnt int 
set @sno = (select sno from inserted)
set @cnt = (select count(cno) from sc where sno = @sno)
if(@cnt >= 5)
begin 
print '你的選課已達上限'
rollback tran
end
else begin
print '選課成功'
commit tran
end

4)創建觸發器,實現刪除STU表某學生的記錄,注意完整性概念保證,使用用instead of
instead of 用法


create trigger del_stu on stu
instead of delete
as begin 
delete stu where sno = (select sno from deleted)
delete sc where sno =(select sno from deleted)
end

5)創建觸發器,實現“男子漢的培養”課程限男生選修。(注:在課程表中添加一條記錄“男子漢的培養”)


create trigger man_sc on sc
after insert 
as
begin tran p_num
declare @sno varchar(4)
declare @sex bit
declare @cno varchar(4)
set @sno = (select sno from inserted)
set @sex = (select sex from stu where sno = @sno)
set @cno = (select cno from inserted)
if @sex = 1 and @cno = (select cno from cou where cname = '男子漢培養' )
begin 
print '選課成功'
commit tran 
end
else begin
print '男生才能選'
rollback tran
end

7.綜合應用:
設系統增加一個需求,爲stu表添加一個sum_credit字段,填寫該字段的數值
(提示:原已選修的課程所獲得的學分必須計算統一,以後每選修一門課,若成績滿足>=60分條件則獲得自動獲取該課程學分)

Alter table stu add sum_credict;
insert into stu
select sum(credit) 
from (
select stu.sno,(case when grade>=60 then credit else 0 end) credit
from stu
left join sc on stu.sno=sc.sno 
left join cou on sc.cno=cou.cno) a
group by sno

思考題:
爲以下錄入記錄要求設計界面,可以使用java、net或javascript實現後截圖
爲stu設計錄入界面,並編程實現之
在這裏插入圖片描述
爲COU表設計錄入界面,並編程實現之

爲SC表設計錄入界面,並編程實現之
要求:附界面及運行結果。

如有錯誤,請指出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章