sql數據庫習題總集

基礎查詢

1.顯示所有年齡不到20歲的所有男生信息

Use jxgl
go
Select *
From s
Where sex=’男’ and datediff(yy,birth,getdate())<20

2.查詢書名中含有“數據庫”的圖書信息

Select *
From c
Where cname like ‘%數據庫%’

3.查詢書名中含有“DB_“的圖書信息

Select *
From c
Where cname like ‘%DB@_%’escape ‘@’

4.查詢姓名以“張”或“李”開頭的所有同學的信息

Select *
From s
Where sname like ‘[張李]%’

5.查詢姓名不是以“張”或“王”開頭的所有同學的信息

Select *
From s
Where sname not like ‘[張李]%’

6.查詢圖書定價在20至50元的圖書信息

Select *
Into aa
From book
Where price between 20 and 50

7.查詢既不是“清華大學出版社”,也不是“高等教育出版社的”的圖書信息

Select *
From book
Where bpc not in (‘清華大學出版社’,‘高等教育出版社’)

8.查詢BOOK表中的圖書號、書名、圖書價格及六折後的價格,並將六折後價格設置別名爲“折後價”,將查詢結果生成一個新表

use jxgl
go
select bno 圖書號,bname 書名,price 圖書價格,0.6*price 折後價
Into NEWBOOK
from book

9.查詢清華大學出版社所有的圖書信息,並按照定價降序排列;

use jxgl
go
select bno 圖書號,bname 書名,price 圖書價格,0.6*price 折後價
from book

10.查詢出版社爲“清華大學出版社”和“高等教育出版社”的所有價格大於30的圖書信息,並按照定價升序排序;

use jxgl
go
select *
from book
where bpc in ('清華大學出版社','高等教育出版社') and price>30
order by price asc

11.查詢BOOK表中清華大學出版社的圖書信息,要求顯示定價排前10的圖書信息
use jxgl
go
select top 10
from book
where bpc in (‘清華大學出版社’)
order by price asc
12.查詢所有先修課爲空值的課程編號,課程名及學分

use jxgl
go
select cno,cname,credit
from c
where tperiod is null

13.查詢已開設的課程的課程號,並去掉重複行;

use jxgl
go
select distinct cno
from c

14.查詢開設過的課程總門數;

use jxgl
go
select count(*)
from c

15.查詢每個同學選修課程的信息,輸出學號,總分數,平均分,最高分和最低分

```bash
use jxgl
go
select count(*)
from c
use jxgl
go
select sno 學號,sum(grade) 總分,avg(grade) 平均分,max(grade) 最高分 ,min(grade) 最低分
from sc
group by sno

16.將全部選修成績大於等於60分的課程,按照課程號分組求出該課程的平均分,顯示平均分大於70分的課程的課程號和平均分。

use jxgl
go
select cno 課程號,avg(grade) 平均分
from sc
where grade>=60
group by cno
having avg(grade)>70

綜合查詢

(1)查詢災害信息工程系的學生數據並保存到ZHXX表中;

Use jxgl
Go
Select sno,sname,sex,birth,homadd,dname
Into ZHXX
From s,dept
Where s.dno=dept.dno and dname=’災害信息工程系’

(2)查詢選修了課程號爲“2008583”的所有學生的學號、姓名、所在系名稱;

Use jxgl
Select s.sno,sname,dname
From s,sc,dept
Where s.sno=sc.sno and s.dno=dept.dno and cno=’2008583’
Group by s.ano,sname,dname

(3)查詢各系的女生人數,並分別對列重命名爲“系名”和“女生人數”;

Use jxgl
Go
Select dname 系名,count(distinct sno) 女生人數
From s,dept
Where dept.dno=s.dno and sex=’女’
Group by dname

(4)查詢每門課程的課程號、課程名、最高分、最低分和平均分;

Use jxgl
Go
Select c.cno 課程號,cname 課程名,max(grade) 最高分,min(grade) 最低分,avg(grade) 平均分
From c,sc
Where c.cno=sc.cno
Group by c.cno,cname

(5)查詢每門課程成績都在90分以上學生的學號、姓名和所在系名稱;

Use jxgl
Go
Select s.sno,sname,dname
From s,sc,dept
Where s.sno=sc.sno and s.dno=dept.dno
Group by s.sno,sname,dname
Having min(grade)>90

(6)查詢選修“2008583”課程的學生中,成績比全校該門課程平均成績高的學生人數;

Use jxgl
Go
Select count(distinct sno)
From sc
Where grade>
(select avg(grade)
From sc
Where cno=’2008583’ and cno=’2008583’)

(7)查詢各系的學生人數、開設課程門數,要求輸出系名、學生人數和課程門數;

Use jxgl
Go
Select dname 系名,count(distinct s.sno) 學生人數,count(distinct cno)課程門數
From s,sc,dept
Where s.sno=sc.sno and s.dno=dept.dno
Group by dname

(8)查詢比“機械工業出版社”出版的所有圖書的定價都高的書號、書名和出版社;

Use jxgl
Go
Select bno 書號,bname 書名,bpc 出版社
From book 
Where price>
(select max(price)
From book 
Where bpc=’機械工業出版社’
And bpc<>’機械工業出版社’)

(9)查詢沒有使用“數據庫系統概論”作爲教材的課程名稱;
!=也是不是

Select cname 課程名
From c,book
Where bname not in (‘數據庫系統概論’) and c.bno=book.bno

(10)查詢所有沒有選修課程的學生學號和姓名;

Use jxgl
Go
Select sno學號,sname 姓名
From s
Where not exists
(select *
From sc
Where sc.sno=s.sno)

(11)查詢選修了課程“2008583”或者選修了課程“2008585”的學生學號及姓名;

Use jxgl
Go
Select s.sno,sname
From s,sc
Where cno=’2008583’and s.sno=sc.sno
Union
Select s.sno,sname
From s,sc
Where cno=’2008585’and s.sno=sc.sno

(12)查詢與“數據庫系統概論”出版社相同且作者相同的圖書信息;

Select se.bno,se.bname,se.price
From book f,book se
Where f.bname=’數據庫系統概論’  and f.bpc=se.bpc and f.author=se.author and se.bname<>f.bname

```bash
或者


Select *
From book
Where bpc=(select bpc
From book
Where bname=’數據庫系統概論’) and author=(select author
From book
Where bname=’數據庫系統概論’) and bname<>’數據庫系統概論’

(13)查詢選修了課程“2008583”但沒有選修課程“2008585”的學生學號及姓名。

Select s.sno,sname
From s,sc
Where cno=’2008583’ and s.sno=sc.sno
Except
Select s.sno,sname
From s,sc
Where cno=’2008585’and s.sno=sc.sno

期中考試

一、根據以下要求,完成相應的SQL語句。
(1)創建一個SPJ庫,該數據庫的主數據文件的邏輯名稱是spj_data,操作系統文件是spj.mdf,初始大小是10MB,最大是30MB,以10%的速度增加;該數據庫的日誌文件的邏輯名稱是spj_log,實際文件名是spj.ldf,初始大小是3MB,最大是10MB,以1MB的速度增加,文件存儲在D盤data文件夾上。(10分)

create database spj
on(name=spj_data,filename='D:\data\spj.mdf',size=10mb,maxsize=30mb,filegrowth=10%) 
log on (name=spj_log,filename='D:\data\spj.ldf',size=3mb,maxsize=10mb,filegrowth=1mb)

(2)創建一張零件表P,包括以下字段:Pno(零件號) char(2)不爲空,主鍵;Pname(零件名)varchar(10)不爲空;color(顏色)varchar(10) 可爲空;weight(重量) int 不爲空,取值範圍0-500。(10分)

create table P 
(pno char(2) not null primary key,
pname varchar(10) not null,
color varchar(10),
weight int not null check(weight>=0 and weight<=500))

(3)查詢供應量在400以上的零件名稱。(5分)

select distinct pname from p,SPJ where P.Pno=SPJ.Pno and qty>400

(4)統計各供應商供應零件和供應工程的數量。(5分)

select sno,count(distinct pno)零件種類,count(distinct jno)工程數目 from spj group by sno

(5)查詢由編號爲S1的供貨商供應零件的工程名稱和工程所在城市。(5分)

select distinct jname,city from j,spj where j.jno=spj.jno and sno='s1'

(6)往零件表中插入一條記錄(Pno=‘p6’,Pname=‘鋼釘’,color=‘灰色’,weight=60)(5分)

insert into P values('p6','鋼釘','灰色',60)

(7)修改由S2供應商供應J1工程的P5零件的供應量爲320。(5分)

update SPJ set qty=320 where sno='s2' and Jno='J1' and Pno='p5'

(8)刪除由西安供應商供應的相關信息。(5分)

delete from spj where sno in(select sno from s where scity='西安')

(9)創建視圖view_one,查詢供應板手的供應商號。(5分)

create rule rule_num as @num>=10 and @num<=2000    sp_bindrule rule_num,'spj.qty'

(10)創建規則rule_num,要求取值在10-2000,並將它綁定到SPJ表的qty字段(5分)。

create view view_one as select distinct sno from spj,p where spj.pno=p.pno and pname='板手'

二、已知某醫院以如下特點:每位醫生屬於且僅屬於一個科室;每個科室可以聘用若干醫生,對每個醫生聘用時存有聘用期限和聘用日期;一個病人可以由不同的醫生爲其診斷,每個醫生可以爲若干病人診治,每次診斷存有就診日期,診斷結果,藥方。設科室的屬性包括科室號,科室名稱,科室主任,科室簡介;醫生的屬性包括工號,姓名和職稱;病人的屬性包括掛號ID,姓名、年齡、住址。
(1)設計E-R圖,註明屬性和聯繫類型。(10分)
(2)將以上E-R轉換爲關係模式,並用下劃線註明主鍵,用波浪線註明外鍵。(10分)

在這裏插入圖片描述

科室(科室號,科室名稱,科室簡介,科主任)
醫生(工號,姓名,職稱,聘用日期,聘用期限,科室號)
病人(掛號Id,姓名,年齡,住址)
診治(工號,掛號id,就診日期,診斷結果,藥方)

**

綜合練習隨堂小測(查詢課後題)

**

五 、 程序設計題 (題 本大題 12 小題 ,共 共 45 分 。) )( 批改參考標準 : 答案不唯一 , 只要求解正確 , 能夠表示數據處理要
求均得分;程序中有語法錯誤,1 處扣 1 分,其中語句結構不正確者本題不得分,英文單詞寫錯酌情扣分)
假設訂單數據庫 ORDERS 中有 3 張表: 客戶表:Customers(Cid,Cname,City),包括的屬性分別爲客戶編號、
客戶名、客戶所在城市;產品表:Products(Pid,Pname,Quantity,Price),包括的屬性分別爲產品編號、產品名稱、產
品銷售數量和產品單價;訂單表:Orders(Ordno, Cid, Pid, Month, Qty),包括的屬性分別爲訂單號、客戶編號、產品
編號、訂貨月份和訂貨數量。
1、 用關係代數表示:查詢沒有“成都”客戶訂購的產品編號及名稱。(3 分)
pid,pname(products) — pid,pname ( city=’ 成都 ’ (customers  orders  products)) …………3 分
2、 用關係代數表示:查詢訂購了客戶“周林”所訂購的所有產品的客戶編號。(3 分)
cid,pid(orders)  ,pid (  cname=’ 周林 ’ (customers  orders)) …………3 分
用 用 SQL 命令完成下列 3-12 的操作:
3、 創建 ORDERS 數據庫,主數據庫文件邏輯名稱爲 orders_data,物理名稱爲 D:\orders_data.mdf,數據文件初
始大小爲 100MB,最大值爲 5000MB,數據文件大小以 10MB 增量增加;日誌文件邏輯名稱爲 orders_log,
物理名稱爲 D:\orders_log.ldf, 日誌文件初始大小爲 10MB,最大值 500MB,日誌文件大小以 5%的增量增
加(6 分)。

CREATE DATABASE ORDERS
ON PRIMARY
( NAME = orders_data,
FILENAME = ' D :\ orders _data.mdf ',
SIZE = 100MB,
MAXSIZE = 5000MB,
FILEGROWTH = 10MB) 
LOG ON
( NAME = orders _log,
FILENAME = ' D :\ orders _log.ldf',
SIZE = 10MB,
MAXSIZE = 500MB,
FILEGROWTH = 5%) 
GO

4、 假設其它表已創建,寫出創建表 Orders 的 SQL 語句,設置相應的主鍵和外鍵(如果有),訂貨月份的默認
值爲 1。數據類型:Ordno、Cid、Pid 均爲字符型,長度爲 10。(6 分)

USE ORDERS
GO
CREATE TABLE ORDERS 
( Ordno char(10) PRIMARY KEY,
cid char(10) NOT NULL FOREIGN KEY REFERENCES CUSTOMERS(cid), 
pid char(10) NOT NULL FOREIGN KEY REFERENCES PRODUCTS(pid),
month INT DEFAULT 1, 
qty INT ) ) 

5、 創建一個規則 PR_RULE,PR_RULE 的值大於等於 0,小於等於 500,並綁定到 Products 表的 Price 列。(3
分)

USE ORDERS
GO
CREATE RULE PR_RULE 
AS @pr>=0 and @pr<=500 
GO
SP_BINDRULE PR_RULE , 'PRODUCTS. Price'
GO

6、向產品表中增加一個產品,名稱爲鼠標,編號爲 P20,單價爲 8.50 元,銷售數量暫時未知。(3 分)

USE ORDERS
GO
INSERT INTO PRODUCTS
VALUES(‘p20’,’鼠標’,8.50,NULL)

7、將所有產品名稱爲“鍵盤”的產品單價提升 10%。(3 分)

USE ORDERS
GO
UPDATE PRODUCTS
SET PRICE=PRICE*1.1
WHERE PNAME=’鍵盤’

8、刪除所有姓“畢”的客戶在 2 月份的所有訂單。(3 分)

USE ORDERS
GO
DELETE FROM ORDERS
WHERE cid IN 
( SELECT cid FROM CUSTOMERS 
WHERE cname LIKE ‘畢%’ ) AND month=2 
  1. 查詢月訂單總數、月均訂貨量,要求賦予別名,並按月均訂貨量輸出前 5 位。(3 分)
USE ORDERS
GO
SELECT TOP 5 Months 月份, COUNT(*) 訂單總數,AVG(Qty) 月均訂貨數量 
FROM ORDERS
GROUP BY Months 
ORDER BYAVG(Qty) DESC 

10、查詢沒有“成都”客戶訂購的產品信息,輸出產品編號,產品名稱和產品單價。(3 分)

USE ORDERS
GO
SELECT Pid, Pname, Price
FROM PRODUCTS
WHERE pid NOT IN
(SELECt pid FROM ORDERS O, CUSTOMERS C 
WHERE O.cid=C.cid AND city=’成都’) 

11、查詢產品名稱“路由器”訂購數量最大的客戶信息,輸出客戶編號,客戶名稱,客戶所在城市。(3 分)

USE ORDERS
GO
SELECT TOP 1 C.CID,CNAME,CITY,SUM(QTY)
FROM PRODUCTS,CUSTOMERS,ORDERS
WHERE PRODUCTS.Pid=ORDERS.Pid and CUSTOMERS.Cid=ORDERS.Cid and Pname=’路由器’
GROUP BY C.CID,CNAME,CITY
ORDER BY SUM(QTY) DESC

12、創建一個視圖 V_CUS,要求輸出訂貨總數量大於 100 的客戶編號、客戶名、產生的訂單數量和訂貨的總
數量。(6 分)

USE ORDERS
GO
CREATE VIEW V_CUS
AS
SELECT ORDERS.cid, cname, SUM(Qty) 總訂貨數量, COUNT(pid) 訂單數
FROM ORDERS,PRODUCTS
WHERE ORDERS.pid=PRODUCTS.pid 
GROUP BY ORDERS.cid, cname
HAVING SUM(Qty)>100 

視圖的創建及應用

(1)基於 S 表創建一個名爲 SVIEW1 的視圖,輸出 sno、sname、sex、birth、homadd,
然後通過該視圖查詢學生信息;

Create view sview1
As
Select sno 學號,sname 姓名,sex 性別,birth 生日,homadd 地址
From s
Go
Select *
From sview1

(2)基於 S 表創建一個男同學的名爲 SVIEW2 的視圖,輸出 sno、sname、homadd,然
後通過該視圖查詢男生信息;

Create view sview2
As
Select sno 學號,sname 姓名,homadd 地址
From s
Where sex=’男’
Go
Select *
From sview2

(3)基於 DEPT 表創建一個學生人數排在前五名的視圖 DEPTVIEW1,輸出 dno、dname、
dheader,然後通過視圖查詢系信息數據;

Create view DEPTVIEW1
As
Select top 5 dno 系號,dname 系名,dheader 院長
From dept
Group by dno,dname,dheader
Order by count(*) desc
Go
Select *
From deptview1

不要group by 那行
(4)基於 S 和 SC 表創建一個按系別分組顯示,選修課程考試平均成績的視圖 SVIEW3,
輸出“系號”、“平均成績”,然後通過視圖查詢’04’系的數據信息;

Create view SVIEW4
As
Select dno 系號,avg(grade) 平均成績
From s,sc
Where s.sno=sc.sno
Group by dno
Go 
Select *
From sview3
Where 系號=’D04’

(5)基於 S、C 和 SC 創建一個聯合視圖 SVIEW4,要求輸出“學號”、“姓名”、“課程名”、“學分”、“總學時”、“成績”和“選修學期”;

Create view SVIEW4
As
Select s.sno 學號,sname 姓名,cname 課程號,credit 學分,tperiod  總學時,grade 成績,tine 選修學期
From s,c,sc
Where s.sno=sc.sno and c.cno=sc.cno

(6)基於(5)中的視圖 SVIEW4 創建視圖 SVIEW5,要求輸出“姓名”、“課程名”和
“成績”;並通過視圖 SVIEW5 查詢“數據庫原理”課程的選修信息;

Create view sview5
As
Select sname 姓名,cname課程名,grade 成績
From s,c,sc
Where  s.sno=sc.sno and c.cno=sc.cno
Go
Select *
From sview5
Where 課程名=’數據庫原理’

(7)基於(5)中創建的視圖 SVIEW4 進行修改,要求輸出“姓名”、“課程名”和“成
績”;並對該視圖進行加密;

Use jxgl
Go 
Alter view SVIEW4
With encryption
As
Select sname 姓名,cname 課程名,grade 成績
From s,c,sc
Where s.sno=sc.sno and c.cno=sc.cno

(6)查看視圖的定義;

Sp_helptext sview4

(8)將視圖 SVIEW5 重新命名爲 STUVIEW5;

Sp_rename’SVIEW5’,’STUVIEW5’

(9)將視圖 STUVIEW5 刪除;

Use jxgl
Go
Drop view  STUVIEW5

(10)通過(1)中創建的名爲 SVIEW1 的視圖,向 S 表中插入數據(’15043102’,’蘭一
飛’,’男’,’1993-11’,’北京市通州區焦王莊’);

Use jxgl
Go
Insert into SVIEW1 
Values(’15043102’,’蘭一飛’,’男’,’1993-11’,’北京市通州區焦王莊’)

(11)通過 SVIEW1 將(10)中插入的學號爲 115043102 的學生姓名更新爲“蘭飛”;

Use jxgl
Go
Update SVIEW1 
Set 姓名=‘蘭飛’
Where 學號=115043102

(12)通過(1)中創建的名爲 SVIEW1 的視圖,刪除所有男同學的信息。

Use jxgl
Go
delete  from SVIEW1
Where 性別=‘男’

唯一聚簇索引

1、實驗作業
(1)在 S 表 sno 列上創建一個唯一聚簇索引 S_INDEX,索引按列順序爲升序,填充因子50%;

use jxgl
go
create unique clustered index S_INDEX
on s(sno asc)
WITH FILLFACTOR = 50

(2)在 DEPT 表 dname 列上創建一個唯一非聚簇索引 DEPT_INDEX,索引按列順序爲降
序;

use jxgl 
go 
create unique nonclustered index DEPT_INDEX 
on dept (dname desc)

(3)用系統存儲過程 SP_HELPINDEX 查看 S 表的索引信息;

SP_HELPINDEX s

(4)用系統存儲過程將 S 表的索引 S_INDEX 重新命名爲 SNO_INDEX;

SP_RENAME ‘s.S_INDEX’,’SNO_INDEX’

(5)將 S 表的索引“SNO_IINDEX”刪除。

drop index s.SNO_IINDEX

(6)在 SC 表上創建一個名爲 SC_INDEX 的非聚簇複合索引,索引關鍵字爲
sno,cno,升序,填充因子 50%。

USE JXGL
GO
CREATE NONCLUSTERED INDEX SC_INDEX
ON SC(sno ASC , cno ASC)
WITH FILLFACTOR = 50

2、實驗作業
(1)爲 C 表的 credit(學分)字段創建缺省約束,缺省值爲 4;

alter table C  
add constraint default_credit  
default ‘4’for credit

(2)爲 S 表的 sex(性別)字段創建檢查約束,值是 0 或 1;

alter table S 
add constraint check_sex  
check(sex=’0’or sex=’1’)

(3)將 S 表的 sno(學號)設爲主鍵(假如在創建表時沒有設置主鍵約束);

alter table S 
add constraint PK_SNO 
primary key clustered(sno)

(4)爲 SC 表 grade(成績)字段創建一個檢查約束,使成績值在 0-100 之間。

USE JXGL
GO
ALTER TABLE SC
ADD CONSTRAINT CHECK_GRADE
CHECK (grade>=0 and grade<=100)

(5)爲 C 表的 cname 字段創建唯一約束;

alter table C
add constraint unique_CNAME 
unique nonclustered(cname)

(6)爲表 S 創建外鍵 dno,外鍵 dno 參考表 DEPT 中的主鍵 dno;

alter table S
add constraint FK_DNO
foreigh key(dno) references DEPT(dno)

(6) 創建一個名爲 SEX_DEFAULT,值爲 1 的默認值,並綁定到表 S 的 Sex 列,然後解
除這個綁定,綁定解除後將此默認值刪除;

create default SEX_DEFAULT as ‘1’
go 
SP_BINDEFAULT SEX_S,’S.sex’ 
go 
SP_UNBINDEFAULT ’S.sex’ 
DROP DEFAULT SEX_DEFAULT
go

(7)創建一個規則 PRICE_RULE,PRICE_RULE 的值大於等於 0,小於等於 500,並綁
定到表 BOOK 的 price 列,然後解除這個綁定,綁定解除後將此規則刪除。

create rule PRICE_RULE 
as 
@price>=0 and @price<=500 
go 
SP_BINDRULE PRICE_RULE,’BOOK.price’ 
go 
SP_UNBINDRULE ’BOOK.price’ 
go 
drop rule PRICE_RULE

T-SQL程序設計

【1】:在 JXGL 中創建兩個自定義數據類型 a 和 b。

USE JXGL
GO
EXEC SP_ADDTYPE a, 'varchar(15)','NULL'
EXEC SP_ADDTYPE b, 'char(15)','NOT NULL'

【2】: :刪除用戶自定義數據類型 a。

USE JXGL
GO
SP_DROPTYPE a

【3】:聲明兩個整型的局部變量:a 和 b,並給 a 賦初值 5,給 b 賦值爲 5 倍的 a,
顯示 b 的結果。

DECLARE @a int, @b int
SET @a=5
SET @b=@a*5
SELECT @b

【4 】: 將 GETDATE 函數的結果轉換爲 varchar 數據類型,並將其打印輸出:
“本信息打印的時間是”。

PRINT '本信息打印的時間是' + (CONVERT(varchar(30), GETDATE( )) )+ ‘。’

【5】: :將 JXGL 數據庫中表 BOOK 裏的 bno 爲 “b01”和“b02”記錄顯示出來,
其餘的用“other”顯示。

CIDP-ZYX
USE JXGL
GO
SELECT BOOK.bno,bno=
CASE bno
WHEN 'b01' THEN 'b01'
WHEN 'b02' THEN 'b02'
ELSE 'OTHER'
END
FROM BOOK

【6】:將 JXGL 中表 BOOK 裏的 price 大於 50 的記錄對應的 price_level 顯示“high”,
price 小於 20 的記錄對應的 price_level 顯示“low”,其餘的顯示“flat”。

USE JXGL
GO
SELECT bno, 'price level'=
CASE
WHEN price> 50 THEN 'high'
WHEN price < 20 THEN 'low'
ELSE 'flat'
END
FROM BOOK

【7】: :定義一個整形變量,如賦值爲 1,顯示“I am a student”,否則顯示“I am a
teacher”。

DECLARE @a int
SELECT @a=2
IF @a=1
BEGIN
PRINT 'I am a student'
END
ELSE
PRINT 'I am a teacher'
GO

【8】: :輸出字符串“student”中每一個字符的 ASCII 值和字符。

DECLARE @p int, @str char(6)
SET @p=1
SET @str='student'
WHILE @p<=DATALENGTH(@str)
BEGIN
SELECTASCII(SUBSTRING( @str,@p,1))AS ASCCODE,
char(ASCII(SUBSTRING( @str,@p,1)))AS ASCCHAR
SET @p= @p+1
END

【實驗 9-9】 】: :使用 IF 語句求 1 到 100 之間的累加和並輸出結果。

DECLARE @sum int, @count int
SELECT @sum=0, @count=1
CIDP-ZYX
LABEL:
SELECT @sum=@sum+@count
SELECT @count=@count+ 1
IF @count<=100
GOTO LABEL
SELECT @sum,@count

【9】: 設置在 9:00 進行一次查詢操作。

USE JXGL
GO
BEGIN
WAITFOR TIME ‘18:00’
SELECT * FROM BOOK
END

【10】:設置在 5 分鐘後進行一次查詢操作。

USE JXGL
GO
BEGIN
WAITFOR DELAY ‘00:00:05’
SELECT * FROM BOOK
END

存儲過程的創建及應用
(1)創建存儲過程 PROC1,要求返回學號和選修課程的門數及平均分;


```bash
use jxgl
go
if exists(select name from sysobjects
where name='PROC1' AND type='P')
drop procedure PROC1
go
create proc PROC1
AS select s.sno 學號, count(cno) 課程數,avg(grade) 平均分
from s,sc
where s.sno=sc.sno
group by s.sno
exec PROC1

(2)創建一個從 S 表查詢學生信息的存儲過程 PROC2,要查詢的系號通過執行語句中
的輸入參數傳遞給存儲過程;

use jxgl 
go 
create proc PROC2
@dno char(10)
as select * from s where dno=@dno
go 
exec proc2 @dno=’D01’

(3)創建一個查詢課程信息的存儲過程 PROC3,要查詢的課程號通過執行語句中的輸
入參數傳遞給存儲過程,要求輸出課程名、選修課程的人數、平均分;

use jxgl 
go
create proc PROC3
@cno char(10)
As select cname 課程名, count(sc.cno) 選課人數, avg(grade) 平均分
from c,sc where c.cno=sc.cno and sc.cno=@cno
group by sc.cno ,c.cname
go
exec PROC3 @cno=’2008010’

(4)爲 JXGL 數據庫建立一個存儲過程 PROC4,通過執行存儲過程將圖書信息添加到
BOOK 表,執行該存儲過程;

use jxgl 
go
create proc PROC4
@bno char(10) = NULL,
@bname varchar(30)=null,
@author varchar(30)=null,
@bpc nvarchar(80)=null,
@price numeric(5,1)=null
As 
If @bno is null or @bname is null or @author is null or @bpc is null
Begin
Print '請重新輸入圖書信息!'
Print '你必須提供圖書的書號、書名、作者、出版社.'
Print '圖書價格可以爲空'
Return 
End
Begin transaction
Insert into book (bno,bname,author,bpc,price)
Values (@bno,@bname,@author,@bpc,@price)
If @@error <>0
Begin
Rollback tran
Return 
End
Commit transaction
Print @bname+'的信息成功添加到表BOOK中'

go
exec PROC4 'B14','JAVA基礎教程','耿祥義','清華大學出版社','45.0'

(5)創建修改指定學生的系別的存儲過程 PROC5,輸入參數爲:學號和修改後的系別,
修改後的系別默認爲“d004”;

Use jxgl
Go
Create proc PROC5
@sno char(10),
@dno char(10)

As 
alter table  s NOCHECK CONSTRAINT all 
update s set  dno=@dno where sno=@sno
Go
Exec PROC5  @sno='125011502', @dno='d004'

(6)創建帶默認值參數的存儲過程 PROC6,輸入參數爲書名(默認值爲書名含有“數
據庫”的圖書),要求輸出版社、定價和作者,並執行該存儲過程;

Use jxgl
Go
Create proc PROC6 
@bname varchar(30)=’%數據庫%’
As select bpc 出版社, price 定價, author 作者
From book  where bname like @bname
Go
Exec PROC6 --exec PROC6 ‘高等數學’	

(7)創建計算 1+2+3…一直加到指定值的存儲過程 PROC7,要求:計算的終值由輸入
參數決定,計算結果由輸出參數返回給調用者;

Create proc PROC7
@sum int OUTPUT ,
@count int ,
@num int 
As
Label:select @sum=@sum+@count
Select @count=@count+1
If @count<=@num
Goto label
Go

@sum int, @count int, @num int
Set @sum=0
Set @count=1
Exec PROC7 @sum OUTPUT,@count,@num=100
print @sum

(8) 創建帶輸入和輸出參數的存儲過程 PROC8,當輸入學號時,給出該同學的姓名,性別,課程平均分和最低分;調用存儲過程 PROC8:查詢學號爲“115043101” 同學的信息;

use jxgl 
go 
create proc PROC8
@sno char(10),
@avgpjf int OUTPUT,
@mincj int OUTPUT
as select @avgpjf=avg(grade) from sc where sno=@sno
select @mincj=min(grade) from sc where sno=@sno
select sname 姓名, sex 性別, @avgpjf 平均分, @mincj 最低分
from s,sc
where s.sno=sc.sno and sc.sno=@sno
go
declare @avg1 int
declare @min1 int 
exec PROC8 '125051501   ',@avg1 OUTPUT ,@min1 OUTPUT

(9)查看中存儲過程 PROC8 的定義;

Sp_help PROC8 

(10)把(8)中存儲過程 Proc8 重命名爲 PSTU;

sp_rename ‘PROC8’ ,’PSTU’

(11)把(10)中存儲過程 PSTU 刪除。

drop PRODEDURE.PSTU

觸發器的創建及應用

5、實驗作業
(1)爲 S 表創建一個插入觸發器 S_INSERT,當向 S 表中添加數據時,如果添加的學 生性別不是“男”或者“女” ,則將禁止插入該學生的信息;

USE jxgl
GO 
CREATE TRIGGER S_INSERT ON S 
FOR INSERT 
AS
IF EXISTS 
(SELECT * 
FROM INSERTED 
WHERE sex<>'男' or sex<>'女') 
BEGIN 
PRINT'性別錯誤' 
ROLLBACK
END 
GO

(2)爲 S 表建立刪除觸發器 S_DELETE,在刪除學生記錄時自動更新 DEPT 表中相應 系的學生人數;

CREATE TRIGGER S_DELETE ON S
FOR DELETE
AS
IF UPDATE(dno) 
BEGIN UPDATE DEPT 
SET Snum= 
(SELECT COUNT(S.sno) 
FROM S,INSERTED I 
WHERE S.dno=I.dno) 
FROM DEPT,INSERTED I 
WHERE DEPT.dno=I.dno 
UPDATE DEPT 
SET snum= 
(SELECT COUNT(S.sno) 
FROM S,DELETED E 
WHERE S.dno=E.dno) 
FROM DEPT, DELETED E 
WHERE DEPT.dno=E.dno 
END 
GO

(3)爲 DEPT 表建立刪除觸發器 D_DELETE,在刪除系部信息時,如果被刪除的系部 有學生,則禁止刪除操作;

CREATE TRIGGER D_DELETE ON DEPT
FOR DELETE 
AS 
IF(EXISTS 
(SELECT dno FROM s
WHERE dno in(Select dno FROM deleted))) 
BEGIN
PRINT '刪除記錄操作不能完成!'
ROLLBACK TRANSACTION 
RETURN 
END 
GO 

(4)爲 BOOK 表創建一個更新觸發器 B_UPDATE,當修改 BOOK 表中清華大學出版社 的圖書定價時,如果修改值大於 1000,則不能修改此圖書的定價;

USE 
JXGL 
GO 
CREATE TRIGGER B_UPDATE ON  BOOK
FOR UPDATE 
AS
if exists
(select * from inserted
where price >1000 and bpc='清華大學出版社')
begin
print '修改值大於 1000,則不能修改此圖書的定價'
ROLLBACK
END 
GO 

(5)爲 SC 表定義一個插入和更新觸發器 SC_IN_UP,在此觸發器中保證成績在 0~100;

USE 
jxgl 
GO 
CREATE 
TRIGGER SC_IN_UP ON SC
FOR INSERT,UPDATE 
AS IF EXISTS 
(SELECT*FROM INSERTED 
WHERE grade<0 or grade>100) 
BEGIN PRINT '成績必須在 0~100的範圍內' 
ROLLBACK 
END 
GO 

(6)爲 C 表定義一個插入觸發器 C_INSERT,實現:向 C 表添加一行數據,確保選用 教材的圖書(bno)存在 BOOK 表中;

USE jxgl 
GO 
CREATE TRIGGER C_INSERT ON C
FOR INSERT 
AS 
IF(not EXISTS 
(SELECT bno FROM C 
WHERE bno in(Select bno FROM inserted))) 
BEGIN 
PRINT '插入操作不能完成!'
PRINT '該圖書不存在.'  
ROLLBACK TRANSACTION 
RETURN
END
GO 

(7)查看 BOOK 表中的觸發器信息;

EXEC SP_HELPTRIGGER BOOK

(8)查看觸發器 B_UPDATE 的相關性;

EXEC SP_DEPENDS 'B_UPDATE'

(9)刪除觸發器 B_UPDATE。

DROP TRIGGER B_UPDATE

【1】:當某系增加一名學生,即向表 S 中 插入一行數據時,需要更改該學生所在
系的記錄,以增加該系的學生總人數。用 請使用 INSERT 觸發器自動完成這
個工作。

USE jxgl
GO
CREATE TRIGGER S_I ON S
FOR INSERT
AS
DECLARE @nums tinyint
SELECT @nums =d.snum
FROM DEPT D , INSERTED I
WHERE D.dno = I.dno
IF (@nums > 0)
BEGIN
UPDATE DEPT
SET snum = snum + 1
FROM DEPT D , INSERTED I
WHERE D.dno = I.dno
END
ELSE
BEGIN
UPDATE DEPT
SET snum =
( SELECT COUNT(S.sno)
FROM S , INSERTED I
WHERE S.dno = I.dno )
FROM DEPT D, INSERTED I
WHERE DEPT. dno = I.dno
END
GO

思考:向 S 表中插入數據行,測試某系部學生人數的變化;理解該存儲過程的執行過程。
【2】: :爲表 S 創建一個 刪除觸發器,當刪除表 S 中的一個學生信息時,將表 SC
中該同學相應的成績記錄刪除掉。

USE JXGL
GO
CREATE TRIGGER S_D ON S
FOR DELETE
AS
DECLARE @sno char(8)
SELECT @sno=DELETED.sno FROM DELETED
DELETE FROM SC
WHERE SC.sno=@sno

【3】:爲 S 表建立 UPDATE 觸發器,在學生數據變更時自動更新 DEPT 表的學
生人數。

USE JXGL
GO
CREATE TRIGGER S_U ON S
FOR UPDATE
AS
IF UPDATE(dno)
BEGIN UPDATE DEPT
SET Snum =
( SELECT COUNT(S.sno)
FROM S, INSERTED I
WHERE S.dno = I.dno )
FROM DEPT, INSERTED I
WHERE DEPT. dno = I.dno
UPDATE DEPT
SET snum =
( SELECT COUNT ( S.sno )
FROM S , DELETED E
WHERE S.dno= E.dno )
FROM DEPT, DELETED E
WHERE DEPT . dno= E. dno
END
GO

【4】: 在 C 表中定義一個插入和更新觸發器 C_IN_UP,在此觸發器中保證學分
在 1~6 的範圍內。( 該列子瞭解,能用約束實現的首先考慮基本約束)

USE jxgl
GO
CREATE TRIGGER C_IN_UP ON C
FOR INSERT, UPDATE
AS IF EXISTS
( SELECT * FROM INSERTED
WHERE credit<1 or credit>6 )
BEGIN PRINT ‘學分必須在 0~6 的範圍內’
ROLLBACK
END
GO

【5】:向 SC 表添加一行數據,檢查所插入數據的有效性。確保學生(sno)存在S 表中,課程(cno)存在於 C 表中。( 該列子瞭解,能用約束實現的首先考慮基本約束)

USE JXGL
GO
CREATE TRIGGER SC_I
ON SC
FOR INSERT
AS IF ( ( NOT EXISTS
( SELECT sno FROM S
WHERE sno IN
( SELECT sno FROM INSERTED ) ) )
OR ( NOT EXISTS
( SELECT cno FROM C
WHERE cno IN
( SELECT cno FROM INSERTED ) ) ) )
BEGIN
PRINT ‘添加記錄操作不能完成!’
PRINT ‘輸入的學號或課程號有錯誤。’
ROLLBACK TRANSACTION
END

【實驗 11-6】 】:爲 BOOK 表創建刪除觸發器,保證被選爲教材的圖書數據不能刪除。(該 該
列子瞭解,能用約束實現的首先考慮基本約束)

CREATE TRIGGER BOOKR_DELETE ON BOOK
FOR DELETE
AS
IF (EXISTS
( SELECT bno FROM C
WHERE bno in ( Select bno FROM deleted ) ) )
BEGIN
PRINT ‘刪除記錄操作不能完成!’
PRINT ‘該圖書被選爲課程的教材。‘
ROLLBACK TRANSACTION
RETURN
END
GO

數據庫安全性
5、實驗作業
(1)創建一個登錄帳戶 lm,密碼爲 1226、使用的默認數據庫爲 JXGL;創建登錄帳戶
zxy,密碼爲 615,使用默認數據庫爲 MODEL;

EXEC SP_ADDLOGIN 'lm','1226', 'JXGL' 
EXEC SP_ADDLOGIN 'zxy', '615', 'MODEL'

(2)查看登錄帳戶 lm;刪除登錄帳戶 zxy;

EXEC SP_HELPLOGINS 'lm'
EXEC SP_DROPLOGIN 'zxy'

(3)在混合驗證模式下,爲數據庫 JXGL 登錄帳戶”lm”和“zxy”創建同名的數據庫用戶;

use jxgl
go
EXEC SP_GRAWINDOWSBACCESS 'lm'
EXEC SP_GRAWINDOWSBACCESS 'zyx'

(4)使用命令 SP_REVOKEDBACCESS 將數據庫中的“zxy”刪除掉;

SP_REVOKEDBACCESS 'zxy'

(5)將登錄名 zxy 加到 sysadmin 角色中;

SP_ADDSRVROLEMEMBER 'zxy', sysadmin

(6)增加一個叫 fz 的自定義數據庫角色;

SP_ADDROLE 'fz', dbo

(7)使用系統存儲過程 SP_ADDROLEMEMBER 將數據庫用戶 lm,zxy 作爲成員添加
到數據庫角色 fz 中,再將 lm 從數據庫角色 fz 中刪除;

EXEC SP_ADDROLEMEMBER 'fz',lm
EXEC SP_ADDROLEMEMBER 'fz',zyx
go
SP_DROPROLEMEMBER 'fz',lm

(8)授予用戶 lm 在數據庫 JXGL 中創建表及對學生表具有查詢、插入權的許可;

GRANT CREATE TABLE TO lm
GRANT SELECT ,INSERT ON C TO lm

(9)撤消用戶 lm 在數據庫 JXGL 中創建表及對學生表具有查詢、插入權的許可;

REVOKE CREATE TABLE FROM lm
REVOKE SELECT,INSERT ON C FROM lm

(10)禁止用戶 lm 在數據庫 JXGL 中對學生表執行插入、刪除操作。

DENY INSERT, DELETE ON S TO lm

遊標對應三道練習題:
(1)定義一個遊標S_COURSOR1,通過遊標將學生表S中性別爲男的學生信息顯示出來;

USE JXGL
GO
DECLARE @sno  char(10),
         @sname  char(10),
		 @sex  char(2),
		 @birth  smalldatetime,
		 @endate smalldatetime,
		 @homadd  nvarchar(40),
		 @dno  char(10)
--聲明遊標
DECLARE  S_COURSOR1  SCROLL CURSOR
FOR 
SELECT sno,sname,sex,birth,endate,homadd,dno 
FROM s 
where sex='男'
FOR READ ONLY
--打開遊標
OPEN S_COURSOR1
--提取數據
FETCH FROM S_COURSOR1 INTO @sno,@sname,@sex,@birth,@endate,@homadd,@dno
WHILE @@FETCH_STATUS=0
             BEGIN
              PRINT '學號:'+@sno+'  姓名:'+@sname+'  性別:'+@sex+'     出生日期:'+convert(char(20),@birth,23)+'登記日期:'+convert(char(20),@endate,23)+'住址:'+@homadd+'系號:'+@dno
              FETCH  FROM  S_COURSOR1  INTO  @sno,@sname,@sex,@birth,@endate,@homadd,@dno

              END
--關閉遊標
CLOSE  S_COURSOR1
--釋放遊標
DEALLOCATE  S_COURSOR1

(2)定義一個遊標S_COURSOR2,通過遊標將學生表S中記錄號爲3的學生姓名改爲“李萍”;

use jxgl
go
declare S_COURSOR2 scroll cursor
for
select sname
from s for update of sname
open S_COURSOR2
fetch absolute 3
from S_COURSOR2
update s
set sname='李萍'
where current of S_COURSOR2
fetch absolute 3 from S_COURSOR2
close S_COURSOR2
deallocate S_COURSOR2

(3)定義一個遊標S_COURSOR3,通過遊標將學生表S中“d01”系的學生數據刪除;

use jxgl
go
declare @sno  char(10),
         @sname  nvarchar(10),
		 @sex  char(2),
		 @birth  char(10),
		 @endate  char(10),
		 @homadd  nvarchar(40),
		 @dno  char(10)
declare S_COURSOR3 scroll cursor
for 
select sno,sname,sex,birth,endate,homadd,dno 
from s
order by sname 
open S_COURSOR3
fetch next from S_COURSOR3
into @sno,@sname,@sex,@birth,@endate,@homadd,@dno
while @@FETCH_STATUS=0
begin
if @dno='d01'
delete from s
where current of S_COURSOR3
fetch next from S_COURSOR3
into @sno,@sname,@sex,@birth,@endate,@homadd,@dno
end
close S_COURSOR3
deallocate S_COURSOR3

(4)使用遊標編寫存儲過程,統計圖書的被選爲教材的情況(顯示書名、選該圖書作爲教材的課程號,及選用圖書作爲教材的課程門數);

use jxgl
go
create proc SCSNUMn(@bname char(4))
as begin
declare @cno char(10),@sum int
select @sum=0
declare g_sum cursor for
select bname,cno 
from c,book
where c.bno=book.bno 
open g_sum
fetch next from g_sum into @bname,@cno
while (@@FETCH_STATUS=0)
begin print '書名:'+@bname+'  '+'課程號:'+@cno
select @sum=@sum+1 
fetch next from g_sum into @bname,@cno
end
close g_sum
deallocate g_sum
print   @bname+'作爲教材的課程門數:'+str(@sum)
end
go

(5)以事務的方式向BOOK表中插入三本圖書的信息:(書號:b001,書名:數據庫原理及應用, 出版社:電子工業出版社);(書號:b002,書名:數據庫系統, 出版社:機械工業出版社);(書號:b003,書名:數據庫技術, 出版社:),其中第三本書缺少出版社信息。注:BOOK表的bpc屬性爲NOT NULL。

use jxgl
go 
begin tran BOOK_TRAN
insert into BOOK(bno,bname,bpc)
values('b001','數據庫原理及應用','電子工業出版社')
save tran aa
insert into BOOK(bno,bname,bpc)
values('b002','數據庫系統','機械工業出版社')
insert into BOOK(bno,bname,bpc)
values('b003','數據庫技術',null)
go
if @@error<>0
rollback tran aa
go
commit tran BOOK_TRAN
go

轉換初步的關係模型,並指出每個關係的主鍵和外鍵

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

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