首页 > 代码库 > SQL Server2005基础知识(created by one friend)

SQL Server2005基础知识(created by one friend)

  1 -- 创建表book的Transact-SQL语句:
  2 create database test01
  3 create table test01.dbo.book(
  4 book_id nchar(6) not null,
  5 book_name nchar(30) null,
  6 price numeric(10,2) null,
  7 constraint PK_book primary key clustered(book_id asc)--建立主键
  8 )on [primary]
  9 
 10 -- 创建表author的Transact-SQL语句:
 11 create table test01.dbo.author(
 12 author_name nchar(4) null,
 13 book_id nchar(6) not null,
 14 address nchar(30) null,
 15 constraint FK_book_author foreign key (book_id)
 16 references book(book_id)--建立外键
 17 )on [primary]
 18 --或者建立完表author后,输入以下命令:
 19 alter table author with check
 20 add constraint FK_book_author foreign key (book_id)
 21 references book(book_id)
 22 
 23 --利用Transact-SQL语句创建表booksales
 24 create table booksales (
 25 book_id nchar(6) not null,
 26 sellnum int null,
 27 selldate datetime null
 28 )on [primary]
 29 
 30 --利用insert语句为表booksales添加数据:
 31 insert into booksales(book_id,sellnum,selldate)
 32 values(1,10,04/15/2010)
 33 --或者输入以下命令:
 34 insert into booksales select 1,10,04/15/2010
 35 --利用delete语句删除表booksales的数据:
 36 delete from booksales where book_id=1
 37 --利用update语句为表booksales更新数据:
 38 update booksales set sellnum=20 where book_id=1
 39 
 40 --创建CHECK约束
 41 alter table booksales
 42 add constraint CK_sellnum check(sellnum>=0)
 43 
 44 /*规则是数据库对象,优先级高于CHECK约束。使用时,须先执行创建规则,后执行绑定规则(不能同时执行);
 45 删除时,同样须先解绑规则,再删除规则*/
 46 create rule sellnum_rule as @sellnum>=0--创建规则
 47 exec sp_bindrule sellnum_rule,booksales.sellnum--绑定规则到列
 48 exec sp_unbindrule booksales.sellnum--解绑规则
 49 drop rule sellnum_rule--删除规则
 50 
 51 delete from booksales where year(selldate)<2009
 52 delete from booksales
 53 truncate table booksales--快速删除表中数据,无日志记录
 54 drop table booksales
 55 
 56 
 57 --查询course表中的所有记录。
 58 use teaching
 59 select * from course
 60 
 61 --查询student表中的女生的人数。
 62 select count(*)as 女生人数from student where sex=
 63 
 64 --查询teacher表中每一位教授的教师号、姓名和专业名称。
 65 select teacherno as 教师号,tname as 教师姓名,major as 专业名称from teacher
 66 where prof=教授
 67 
 68 --按性别分组,求出student表中的每组学生的平均年龄。
 69 select sex as 性别,avg(year(getdate())-year(birthday))as 平均年龄from student
 70 group by sex--年龄也可以表示为datediff(year,birthday,getdate())
 71 
 72 --利用现有的表生成新表,新表中包括学号、学生姓名、课程号和总评成绩。
 73 --其中:总评成绩=final*0.8+usually*0.2
 74 select student.studentno as 学号,sname as 学生姓名,classno as 课程号,final*0.8+usually*0.2 
 75 as 总评成绩
 76 into score2
 77 from score,student
 78 where score.studentno=student.studentno
 79 
 80 --统计每个学生的期末成绩平均分
 81 select sname as 学生姓名,student.studentno as 学号,avg(final) as 期末成绩平均分from score,student
 82 where score.studentno=student.studentno
 83 group by student.studentno,sname
 84 
 85 -- 输出student表中年龄最大的男生的所有信息。
 86 select * from student where birthday=(select min(birthday) from student where sex=)
 87 and sex=
 88 --或者输入如下命令
 89 select top 1 * from student where sex= order by birthday
 90 

 91 --查询teacher表中没有职称的职工的教师号、姓名、专业和部门。
 92 select teacherno as 教师号,tname as 教师姓名,major as 专业名称,department as 部门from teacher
 93 where prof is null
 94 
 95 --查询每一位教授的教师号、姓名和讲授的课程名称。
 96 select teacher.teacherno as 教师号,tname as 教师姓名,cname as 讲授课程from teacher,teach_class,course
 97 where prof=教授 and teacher.teacherno=teach_class.teacherno and teach_class.courseno=course.courseno 
 98 
 99 --利用现有的表生成新表,新表中包括学号、学生姓名、课程名称和总评成绩。
100 --其中:总评成绩=final*0.9+usually*0.1
101 select student.studentno as 学号,sname as 学生姓名,cname as 课程名称,final*0.9+usually*0.1 
102 as 总评成绩
103 into score3
104 from score,student,course
105 where score.studentno=student.studentno and course.courseno=score.courseno
106 
107 --统计每个学生的期末成绩高于分的课程门数。
108 select student.studentno as 学号,sname as 学生姓名,count(*)as 课程数from student,score
109 where score.studentno=student.studentno
110 and final>75
111 group by student.studentno,sname
112 
113 --输出student表中年龄大于女生平均年龄的男生的所有信息。
114 select * from student
115 where  sex= 
116 and  DATEDIFF(year,birthday,getdate()) > (
117 select avg(DATEDIFF(year,birthday,getdate()))
118 from student where  sex= ) 
119 
120 --计算每个学生获得的学分。
121 select student.studentno as 学号,student.sname as 学生姓名,sum(credit) as 总学分
122 from student INNER JOIN score 
123        ON student.studentno=score.studentno
124       INNER JOIN course
125        ON course.courseno=score.courseno
126 where  score.final>60
127 group by student.studentno,student.sname
128 
129 --获取入学时间在年到年的所有学生中入学年龄小于19岁的学号、姓名及所修课程的课程名称。
130 select student.studentno as 学号,student.sname as 学生姓名,course.cname as 课程名称
131 from student INNER JOIN score 
132        ON student.studentno=score.studentno
133       INNER JOIN course
134        ON course.courseno=score.courseno        
135 where (substring(student.studentno,1,2)=08 and (datediff(year,birthday,2008-01-01)<19)) 
136       or(substring(student.studentno,1,2)=09 and (datediff(year,birthday,2009-01-01)<19))
137 
138 --查询级学生的学号、姓名、课程名及学分。
139 select student.studentno as 学号,student.sname as 学生姓名,course.cname as 课程名称,
140 credit as 学分
141 from student INNER JOIN score 
142        ON student.studentno=score.studentno
143       INNER JOIN course
144        ON course.courseno=score.courseno
145 where  score.final>60 and substring(student.studentno,1,2)=09
146 group by student.studentno,student.sname,course.cname,credit
147 
148 --查询选修课程的少于门、或期末成绩含有分以下课程的学生的学号、姓名、电话和Email。
149 select  studentno,count(*) as countNUM  
150 into  count1
151 from score
152 group by studentno 
153 GO
154 select distinct student.studentno as 学号,sname as 学生姓名,phone as 电话,Email as 邮箱
155 from student  inner join score 
156               on student.studentno=score.studentno 
157               inner join count1
158               on student.studentno=count1.studentno
159 where  score.final<60 or countNUM<3 
160 order by student.studentno  --可能有学生不但选修课程少于门,而且有不及格的课程,那么他的信息会输出两次,所以加distinct
161 
162 --在course表的cname列上创建非聚集索引IDX_cname。
163 CREATE NONCLUSTERED INDEX IDX_cname ON course(cname)
164 
165 --在student表的studentno和classno列创建唯一索引UQ_stu,若该索引已存在,则删除后重建,并输出student表中的记录
166 IF EXISTS(SELECT name FROM sysindexes WHERE name=UQ_stu)
167    DROP INDEX student.UQ_stu
168 GO
169 CREATE NONCLUSTERED INDEX UQ_stu ON student(studentno,classno)
170 GO
171 SELECT * FROM student
172 
173 --修改UQ_stu的索引属性,当执行多行插入操作时出现重复键值,则忽略该记录,且设置填充因子为80%
174 ALTER INDEX UQ_stu  ON student REBUILD
175   WITH (PAD_INDEX = ON, FILLFACTOR = 80)
176 
177 --创建一个视图v_teacher,查询所有“计算机学院”教师的信息。
178 CREATE VIEW v_teacher
179 AS
180 SELECT *
181 FROM teacher
182 WHERE department = 计算机学院
183 GO
184 SELECT * FROM v_teacher
185 
186 --创建一个视图v_avgstu,查询每个学生的学号、姓名及平均分,并且按照平均分降序排序。
187 CREATE VIEW v_avgstu
188 AS
189 SELECT TOP(100) PERCENT student.studentno, student.sname, AVG(score.final) AS average
190 FROM student, score
191 WHERE student.studentno = score.studentno AND score.final IS NOT NULL
192 GROUP BY student.studentno, student.sname
193 GO
194 SELECT * FROM v_avgstu  ORDER BY average DESC
195 --order by 相关内容不能被存入视图中,仅查询时有效。所以在查询视图时使用它。
196 
197 --修改v_teacher的视图定义,添加WITH CHECK OPTION选项。
198 ALTER VIEW v_teacher
199 AS
200 SELECT * FROM teacher
201 WHERE department = 计算机学院
202 WITH CHECK OPTION
203 
204 --通过视图v_teacher向基本表teacher中分别插入数据,并查看插入数据情况。
205 INSERT INTO v_teacher VALUES(05039,张馨月,计算机应用,讲师,计算机学院)
206 INSERT INTO v_teacher VALUES(06018,李诚,机械制造,副教授,机械学院)
207 GO
208 SELECT * FROM v_teacher
209 SELECT * FROM teacher
210 
211 --通过视图v_teacher将基本表teacher中教师编号为‘05039‘的教师职称修改为‘副教授‘。
212 UPDATE v_teacher
213 SET prof = 副教授
214 WHERE teacherno = 05039
215 GO
216 SELECT * FROM teacher
217 
218 
219 --创建一个名称为StuInfo的存储过程,要求完成以下功能:
220 --在student表中查询级学生的学号、姓名、性别、出生日期和电话个字段的内容
221 
222 --查询是否已存在此存储过程,如果存在,就删除它
223 IF EXISTS (SELECT name FROM sysobjects 
224          WHERE name = StuInfo AND type = P)
225    DROP PROCEDURE StuInfo
226 
227 CREATE PROCEDURE StuInfo 
228  AS
229 Select studentno,sname,sex,birthday,phone        
230 FROM student
231 WHERE substring(studentno,1,2)=08
232 exec StuInfo
233 
234 --创建一个存储过程ScoreInfo,
235 --完成的功能是在表student、表course和表score中查询以下字段:学号、姓名、性别、课程名称、期末分数。
236 CREATE PROCEDURE ScoreInfo 
237  AS
238 Select student.studentno,student.sname,student.sex,course.cname,Score.final        
239 FROM student,course,score
240 WHERE student.studentno=score.studentno 
241     and score.courseno=course.courseno
242 exec ScoreInfo
243 
244 --创建一个带有参数的存储过程Stu_Age,
245 --该存储过程根据输入的学号,在student表中计算此学生的年龄,
246 --并根据程序的执行结果返回不同的值,程序执行成功,返回整数,如果执行出错,则返回错误号。
247 CREATE PROCEDURE Stu_Age 
248     @studentno nvarchar(10),@age int output
249 AS 
250 --定义并初始化局部变量,用于保存返回值
251 DECLARE @ErrorValue int
252 SET @ErrorValue=0
253 --求此学生的年龄
254 SELECT @age=YEAR(GETDATE())-YEAR(birthday) 
255 FROM student
256 WHERE studentno=@studentno
257 --根据程序的执行结果返回不同的值
258 IF (@@ERROR<>0)
259    SET @ErrorValue=@@ERROR
260 RETURN @ErrorValue
261 --由于该存储过程有输出参数,那么必须在执行存储过程前定义一个变量,以接收存储过程要传出的值
262 declare @a int
263 exec Stu_Age @studentno=7,@age=@a OUTPUT
264 select @a
265 
266 /*创建一个INSERT触发器TR_Stu_Insert,当在student表中插入一条新记录时,出发该触发器,并给出”
267 你插入了一条新记录!“的提示信息*/
268 CREATE TRIGGER dbo.TR_Stu_Insert 
269    ON  dbo.student 
270    AFTER INSERT
271 AS 
272 BEGIN
273     DECLARE @msg nchar(30)
274     SET  @msg=你插入了一条新记录!
275     PRINT @msg
276 END
277 
278 insert into student(studentno) 
279 values(0822111209)
280 
281 --创建一个AFTER触发器,要求实现以下功能:
282 --在score表上创建一个插入、更新类型的触发器TR_ScoreCheck,
283 --当在score字段中插入或修改考试分数后,触发该触发器,检查分数是否在-100之间。
284 CREATE TRIGGER TR_ScoreCheck
285 ON score
286 FOR INSERT, UPDATE 
287 AS
288 IF UPDATE(final )
289 PRINT AFTER触发器开始执行……
290 BEGIN
291     DECLARE @ScoreValue real
292     SELECT @ScoreValue=(SELECT final  FROM inserted)
293     IF @ScoreValue>100 OR @ScoreValue<0 
294       PRINT 输入的分数有误,请确认输入的考试分数!
295 END
296 --检验TR_ScoreCheck触发器
297 update score set final=101 where courseno=c05109 and studentno=0822111208
298 
299 --创建一个INSTEAD OF触发器,要求实现以下功能:
300 --在course表上创建一个删除类型的触发器TR_NotAllowDelete,
301 --当在course表中删除记录时,触发该触发器,显示不允许删除表中数据的提示信息。
302 IF EXISTS(SELECT name FROM sysobjects 
303 WHERE name =TR_NotAllowDelete AND type = TR)
304       DROP TRIGGER TR_NotAllowDelete
305 GO
306 CREATE TRIGGER TR_NotAllowDelete
307 ON course
308 INSTEAD OF DELETE
309 AS
310    PRINT INSTEAD OF 触发器开始执行……
311    PRINT 本表中的数据不允许被删除!不能执行删除操作!
312 --检验TR_NotAllowDelete触发器
313 delete from course 
314 
315 --创建在score表上执行UPDATE语句的事务UP_score,并执行。
316 BEGIN TRAN
317   UPDATE dbo.score
318   SET usually=77,final=88
319   WHERE studentno=0824113307 AND courseno=c05109   
320 COMMIT TRAN
321 
322 --练习使用ROLLBACK TRANSACTION语句回滚事务,并查看。
323 BEGIN TRAN
324    INSERT INTO course
325    VALUES(c05135,国际贸易,必修,32,2.0);
326    SAVE TRAN save1;
327    DELETE FROM course
328    WHERE courseno=c05135;
329    ROLLBACK TRAN save1;
330 COMMIT TRAN
331 
332 --练习在student表上进行查询、插入和更新,然后使用sys.dm_tran_locks视图查看锁的信息。
333 BEGIN TRAN
334   SELECT studentno,sname
335   FROM student
336 --WITH(holdlock, rowlock)
337   WHERE studentno=0828261367;
338   INSERT INTO student 
339      VALUES(1028261001,孙释远,,1989-09-09,090512,777,1328909876,sdqd@163.com);
340   UPDATE student
341   SET sname=孙释嘉
342   WHERE studentno=0828261367;
343 --为了查看事务中使用的锁的信息,使用动态管理视图sys.dm_tran_locks。在查询窗口中键入并执行以下SELECT语句来获取锁信息并提交事务。
344 SELECT resource_type, resource_associated_entity_id,
345        request_status, request_mode, request_session_id,
346        resource_description
347 FROM sys.dm_tran_locks
348 WHERE resource_database_id=DB_ID(teaching);
349 --提交事务
350 COMMIT TRAN
351 
352 --创建一个SQL Server登录名USER1,密码为Abc!@#213
353 USE master
354 GO
355 CREATE LOGIN USER1 WITH PASSWORD =Abc!@#213
356 
357 --练习在teaching数据库中为SQL Server登录名USER1添加数据库用户,并取名为USER2,默认架构为TEAC。
358 USE teaching
359 GO
360 CREATE USER USER2 FOR LOGIN USER1
361 WITH DEFAULT_SCHEMA =TEAC
362 
363 --练习将teaching数据库中创建表的权限授予用户USER2。
364 USE teaching
365 GO
366 GRANT CREATE TABLE TO USER2
367 
368 --完整数据库备份
369 USE teaching 
370 GO
371 BACKUP DATABASE teaching 
372 TO  DISK = NF:\sqlprogram_ex\第章\backteaching 
373 WITH  EXPIREDATE = N12/22/2009 00:00:00, 
374 NAME = Nteaching-完整数据库备份,
375 STATS = 10
376 GO
377 --差异备份
378 BACKUP DATABASE teaching 
379 TO  DISK = NF:\sqlprogram_ex\第章\backteaching 
380 WITH  DIFFERENTIAL ,  
381 EXPIREDATE = N12/22/2009 00:00:00, 
382 NOFORMAT, NOINIT,  
383 NAME = Nteaching-差异数据库备份, 
384 SKIP, NOREWIND, NOUNLOAD,  STATS = 10
385 GO
386 declare @backupSetId as int
387 select @backupSetId = position 
388 from msdb..backupset 
389 where database_name=Nteaching and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=Nteaching )
390   if @backupSetId is null 
391    begin 
392     raiserror(N验证失败。找不到数据库“teaching”的备份信息。, 16, 1) 
393    end
394 RESTORE VERIFYONLY 
395 FROM  DISK = NF:\sqlprogram_ex\第章\backteaching 
396 WITH  FILE = @backupSetId, NOUNLOAD,  NOREWIND
397 GO
398 
399 --对数据库teaching进行恢复
400 RESTORE DATABASE teaching 
401 FROM  DISK = NF:\sqlprogram_ex\第章\backteaching 
402 WITH  FILE = 2,  NORECOVERY,  NOUNLOAD,  
403 STATS = 10
404 GO
405 RESTORE DATABASE teaching 
406 FROM  DISK = NF:\sqlprogram_ex\第章\backteaching
407  WITH  FILE = 3,  NOUNLOAD, 
408 STATS = 10
409 GO
410 
411 --创建备份设备
412 USE master
413 GO
414 EXEC master.dbo.sp_addumpdevice 
415 @devtype = Ndisk, 
416 @logicalname = Ndevice1, 
417 @physicalname = NF:\sqlprogram_ex\第章\back_device1.bak
418 GO
419 --备份teaching数据库的事务日志
420 BACKUP LOG teaching 
421 TO  device1 
422 WITH  RETAINDAYS = 3, NOFORMAT, NOINIT, 
423  NAME = Nteaching-事务日志备份, 
424 SKIP, NOREWIND, NOUNLOAD,  
425 STATS = 10
426 GO
427 
428 
429 
430 分别创建增加、删除、更新的触发器(Trigger)来达到两张表之间数据同步的目的。
431 1:数据同步增加:
432 如有两张表——A表和B表,创建触发器使当A表插入数据后B表也同步插入数据。其中B表插入数据的字段需要同A表中的字段相对应。
433 CREATE TRIGGER 触发器名称 
434 ON A表
435 AFTER INSERT 
436 AS BEGIN INSERT INTO 
437 B表(B表字段1,B表字段2,B表字段3)
438 SELECT A表字段1,A表字段2,A表字段3 
439 FROM INSERTED
440 END
441  
442 2.数据同步删除:
443 如有两张表——A表和B表,创建触发器使当A表删除数据后B表也同步删除数据。其中B表与A表应有相应主键关联。
444 CREATE TRIGGER 触发器名称 
445 ON A表 
446 AFTER DELETE 
447 AS BEGIN DELETE B表 
448 WHERE 
449 B表主键 IN( 
450 SELECT A表主键
451 FROM DELETED) 
452 END
453  
454 3.数据同步更新:
455 如有两张表——A表和B表,创建触发器使当A表数据更新后B表也同步更新数据。
456 CREATE TRIGGER 触发器名称
457 ON A表 
458 AFTER UPDATE 
459 AS 
460 update B表
461 SET 
462 B.B表字段1=A.A表字段1  
463 FROM
464 B表 AS B,INSERTED AS A   
465 WHERE B.B表主键=A.A表主键
466 
467 
468 
469 /*
470 SQLsever2005练习:
471 信息表:info
472 学号(nchar(4))stuno  
473 姓名(nchar(8))sname  
474 性别(nchar(2))sex  
475 入学成绩(int)score   
476 出生日期(datetime)birthday
477 
478 成绩表:grade
479 学号(nchar(4))stuno  
480 课程编号(nchar(5))courseno 
481 成绩(int)grade
482 */
483 
484 use teaching  
485 go
486 create table info(
487 stuno nchar(4) not null,
488 sname nchar(8)  null,
489 sex nchar(2)  null,
490 score int null,
491 birthday datetime null,
492 constraint pk_stuno primary key clustered(
493 stuno asc))
494 
495 insert into info
496 select 001,张三,,780,1990-08-15
497 insert into info
498 select 002,小芳,,730,1990-09-22
499 insert into info
500 select 003,小青,,767,1990-05-12
501 insert into info
502 select 004,李四,,770,1990-09-02
503 
504 create table grade(
505 stuno nchar(4) not null,
506 courseno nchar(5)  null,
507 grade int null,
508 )
509 
510 insert into grade
511 select 001,111,100
512 insert into grade
513 select 001,222,89
514 insert into grade
515 select 001,333,88
516 insert into grade
517 select 002,111,97
518 insert into grade
519 select 002,222,94
520 insert into grade
521 select 002,333,93
522 insert into grade
523 select 003,111,98
524 insert into grade
525 select 003,222,95
526 insert into grade
527 select 003,333,91
528 insert into grade
529 select 004,111,99
530 insert into grade
531 select 004,222,90
532 insert into grade
533 select 004,333,82
534 --1,创建一个表的命令
535 
536 
537 
538 
539 select sex as 性别, avg(score)as 平均成绩
540 from info
541 group by sex
542 --2,分别求出男女学生的平均成绩
543 
544 
545 
546 select info.stuno as学号,sname as姓名,courseno as课程编号 from grade,info
547 where grade.stuno=info.stuno and
548 ((courseno=222 and grade.grade=(select max(grade) from grade where courseno=222))
549 or(courseno=111 and grade.grade=(select max(grade) from grade where courseno=111))
550 or(courseno=333 and grade.grade=(select max(grade) from grade where courseno=333)))
551 --3,显示单科成绩最高的学生的学号,姓名及课程编号
552 
553 
554 
555 select info.stuno as学号,sname as姓名,avg(grade) as平均成绩
556 from grade inner join info
557 on grade.stuno=info.stuno
558 group by info.stuno,info.sname
559 having avg(grade)>85
560 --4,显示平均成绩高于分的学生的学号,姓名
561 
562 
563 
564 if exists (select name from sysindexes where name=inx_info)
565 drop index info.inx_info
566 create index inx_info on info(stuno,sname)
567 --5,在信息表中创建非聚集索引,如果该索引存在则删除
568 
569 
570 
571 create view v_info
572 as
573 select info.stuno as 学号,sname as 姓名,avg(grade)as平均成绩
574 from info inner join grade
575 on info.stuno=grade.stuno
576 group by info.stuno,sname
577 select *from v_info
578 --6,建立视图view,查询所有学生的学号,姓名和平均成绩
579 
580 
581 
582 create procedure p_grade
583 @stuno nchar(4)
584 as
585 delete from grade
586 execute p_grade 
587 @stuno=003
588 --7,创建一个存储过程,删除成绩表中指定的记录
589 
590 
591 create trigger t_info on info
592 after delete
593 as 
594 begin delete from grade
595 where stuno in(select stuno from deleted)
596 end
597 --8,在信息表上创建一个触发器trigger,当删除信息表中的记录时,同时删除成绩表中指定的记录
598 
599 
600 
601 select count(stuno) as 学生人数 from info;
602 begin tran
603 save tran savepoint;
604 insert into info
605 select 008,小刘,,20,1989-7-15
606 select count(stuno) as 学生人数 from info;
607 rollback tran savepoint;
608 commit tran
609 select count(stuno) as 学生人数 from info;
610 go
611 --9,先显示信息表中指定的学生人数,开始一个事务,插入一条‘信息’记录,显示‘信息’表中的人数,再回滚事务,再显示‘信息’表中的人数
612 
613 
614 create database jiaoxue 
615 use jiaoxue
616 go
617 alter database jiaoxue add filegroup Testgroup
618 --10,为数据库jiaoxue添加一个名为"Testgroup"的文件组