Tag: SQL预览模式: 普通 | 列表

SQL的触发器

SQL代码
  1. [1].触发器的概念  
  2. 触发器是一种特殊类型的存储过程,当指定表中的数据发生变化时触发器自动生效。它与表紧密相连,可以看做是表定义的一部分。触发器不能通过名称被直接调用,更不允许设置参数。  
  3.   
  4. 在SQL Server中一张表可以有多个触发器。用户可以跟据InsertUpdateDelete语句对触发器进行设置,也可以对一张表上的特定操作设置多个触发器。触发器可以包含复杂的Transact-SQL语句。不论触发器所进行的操作有多复杂,触发器都只作为一个独立的单元被执行,被看作是一个事务。如果在执行触发器的过程中发生了错误,则整个事务将会自动回滚。  
  5.   
  6. [2].触发器的优点  
  7. 1.触发器自动执行  
  8. 对表中的数据进行修改后,触发器立即被激活。  
  9.   
  10. 2.可以调用存储过程  
  11. 为了实现复杂的数据库更新操作,触发器可以调用一个或多个存储过程,甚至可以通过调用外部过程(不是数据库管理系统本身)完成相应的操作。  
  12.   
  13. 3.可以强化数据条件约束  
  14. 触发器能够实现比CHECK约束更为复杂的数据完整性约束。在数据库中,为了实现数据完整性约束,可以使用CHECK约束或触发器。CHECK约束不允许引用其他表中的列来完成检查工作,而触发器可以引用其他表中的列。它更适合在大型数据库管理系统中用来约束数据的完整性。  
  15.   
  16. 4.触发器可以楚止或回滚违反引用完整性的更改  
  17. 触发器可以检测数据库内的操作,从而取消了数据库未经许可的更新操作,使数据库修改、更新操作更安全,数据库的运行也更稳定。  
  18.   
  19. 5.级联、并行运行  
  20. 触发器能够对数据库中的相关表实现级联更改。触发器是基于一个表创建的,但是可以针对多个表进行操作,实现数据库中相关表的级联更改。  
  21.   
  22. 6.同表多触发器  
  23. 一个表中可以同时存在3个不同操作的触发器(InsertUpdateDelete)。  
  24.   
  25. [3].触发器的种类  
  26. SQL Server支持两种类型的触发器:AFTER触发器和INSTEAD OF触发器。  
  27.   
  28. AFTER触发器又称为后触发器,该类触发器是在引起触发器执行的修改语句成功完成后执行。此类触发器只有在执行某一操作(InsertUpdateDelete)之后,触发器才被触发,如果修改语句错误,触发器将不会执行。AFTER触发器只能定义在表上,不能创建在视图上,但可以为针对表的同一操作定义多个触发器。可使用 sp_settriggerorder指定表上第一个和最后一个执行的AFTER触发器,在表上只能为每个INSETR、UpdateDelete操作规程指定第一个执行和最后一个执行的AFTER触发器。  
  29.   
  30. INSTEAD OF触发器又称为替代触发器,当引起触发器执行的修改语句停止时,该类触发器代替触发操作执行。它可以在表上定义,也可以在视图上定义。对于每个触发操作(InsertUpdateDelete),只能定义一个INSTEAD OF触发器。  
  31.   
  32. INSTEAD OF触发器与AFTER触发器的最大不同之处在于INSTEAD OF触发器并不是在执行预定义的操作(如InsertUpdateDelete)时被触发,而仅仅是执行触发器本身。  
  33.   
  34. [4].触发器的创建  
  35.   
  36. 1.使用企业管理器创建触发器  
  37.   
  38. 在企业管理器中为数据库“MR_SQL”中的“MR_Stu_XX”表创建一个名为 “TRI_StuXX_Insert”的触发器,实现在“MR_Stu_XX”表中添加数据时,在“TRI_pp”表中自动添加数据。  
  39.   
  40. 操作步骤如下:  
  41.   
  42. (1)在操作系统的任务栏中单击“开始”菜单,选择“程序”→“Microsoft SQL Server”→“企业管理器” 命令,打开控制台目录。  
  43.   
  44. (2)在控制台目录中依次展开Microsoft SQL Server、SQL Server组、服务器、数据库的节点。  
  45.   
  46. (3)选择指定数据库中的指定表,单击鼠标右键,在快捷菜单中选择“所有任务”→“管理触发器”命令。  
  47.   
  48. (4)执行“管理触发器”命令后,打开“触发器属性”对话框,如图1所示。在“名称”文本框中输入触发器的名称,例如用触发器名“TRI_StuXX_Insert”替换[TRIGGER NAME],如图2所示。  
  49.   
  50. (5)删除FOR关键字后面的UpdateDelete,使触发器具有添加(Insert)功能,如果让触发器具有更新或删除的功能,在FOR关键字后面保留Update或 DeleteInsert 、UpdateDelete可以同时使用。  
  51.   
  52. (6)在“文本”文本框中输入触发器文本,SQL语句如下。  
  53. Insert INTO TRI_pp (MR_id,MR_name,MR_char,MR_sum,MR_eng) VALUES ('001','张三',0.0,0.0,0.0)  
  54.   
  55. (7)如果没有任何错误,单击“应用”按钮,将触发器保存到数据库中。  
  56.   
  57.   
  58. 2.使用Transact-SQL创建触发器  
  59.   
  60. Create TRIGGER语句用于创建触发器,触发器是一种特殊的存储过程,在用户试图对指定的表执行指定的数据修改语句时自动执行。 SQL Server 允许为任何给定的InsertUpdateDelete语句创建多个触发器。  
  61.   
  62. 语法:  
  63.   
  64. Create TRIGGER trigger_name  
  65.   
  66. ON { table | view }  
  67.   
  68. WITH ENCRYPTION ]  
  69.   
  70. {  
  71.   
  72.    { { FOR | AFTER | INSTEAD OF } { [ Insert ] [ , ] [ Update ] }  
  73.   
  74.       [ WITH APPEND ]  
  75.   
  76.       [ NOT FOR REPLICATION ]  
  77.   
  78.       AS  
  79.   
  80.       [ { IF Update ( column )  
  81.   
  82.       [ { AND | or } Update ( column ) ]  
  83.   
  84.          [ ...n ]  
  85.   
  86.       | IF ( COLUMNS_UpdateD ( ) { bitwise_operator } updated_bitmask )  
  87.   
  88.         { comparison_operator } column_bitmask [ ...n ]  
  89.   
  90.       } ]  
  91.   
  92.       sql_statement [ ...n ]  
  93.   
  94.    }  
  95.   
  96. }  
  97.   
  98. 参数说明:  
  99.   
  100. l    trigger_name:触发器的名称。触发器名称必须符合标识符规则,并且在数据库中必须惟一。可以选择是否指定触发器所有者名称。  
  101.   
  102. l    table | view:执行触发器的表或视图,有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。  
  103.   
  104. l    AFTER:指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才被激活。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。  
  105.   
  106. l    INSTEAD OF:指定执行触发器而不是执行触发 SQL 语句,从而替代触发语句的操作。  
  107.   
  108. l    WITH APPEND:指定应该添加现有类型的其他触发器。只有当兼容级别是65或更低时,才需要使用该可选子句。  
  109.   
  110. l    NOT FOR REPLICATION:表示当复制进程更改触发器所涉及的表时,不应执行该触发器。  
  111.   
  112. l    AS:触发器要执行的操作。  
  113.   
  114. l    sql_statement:触发器的条件和操作。触发器条件指定其他准则,以确定DeleteInsertUpdate语句是否导致执行触发器操作。  
  115.   
  116. l    column:要测试 InsertUpdate操作的列名。该列可以是SQL Server支持的任何数据类型。  
  117.   
  118. l    bitwise_operator:用于比较运算的位运算符。  
  119.   
  120. l    updated_bitmask:整型位掩码,表示实际更新或插入的列。  
  121.   
  122. l    comparison_operator:比较运算符。使用等号(=)检查updated_bitmask中指定的所有列是否都实际进行了更新。使用大于号(>)检查 updated_bitmask中指定的任一列或某些列是否已更新。  
  123.   
  124. l    column_bitmask:要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。  
  125.   
  126. 本示例是建立两个相关表“MR_Stu_XX”和“MR_Stu_CJ”,它们都有“学生编号”和 “学生姓名”字段,并且类型相同。在“MR_Stu_XX”表中创建三个触发器,在对“MR_Stu_XX”表进行添加修改的同时,对 “MR_Stu_CJ”表也进行相应的操作。  
  127. 操作步骤如下:  
  128. (1)在“MR_SQL”数据库中创建“MR_Stu_CJ”表和 “MR_Stu_XX”表。  
  129. (2)为“MR_Stu_XX”表创建触发器,SQL语句如下:  
  130. Insert语句创建触发器,当在 “MR_Stu_XX”表中添加数据时,“MR_Stu_CJ”表也添加相应的数据。SQL语句如下:  
  131.   
  132. USE MR_SQL  
  133. GO  
  134. Create TRIGGER TRI_StuXX_Insert ON dbo.MR_Stu_XX  
  135. FOR Insert  
  136. AS  
  137. DECLARE @id Char(4),@name Char(10)  
  138. Select @id=学生编号,@name=学生姓名  from inserted  
  139. Insert INTO MR_Stu_CJ (学生编号,学生姓名,语文,数学,英语) VALUES (@id,@name,0.0,0.0,0.0)  
  140. GO  
  141. 注意:在表中添加数据时,将添加的数据存放在系统临时表“inserted”中。  
  142.   
  143. Delete语句创建触发器,当在 “MR_Stu_XX”表中删除数据时,“MR_Stu_CJ”表也删除相应的数据。SQL语句如下:  
  144. USE MR_SQL  
  145. GO  
  146. Create TRIGGER TRI_StuXX_Delete ON [dbo].[MR_Stu_XX]  
  147. FOR Delete  
  148. AS  
  149. DECLARE @id char(4),@name char(10)  
  150. select @id=学生编号,@name=学生姓名 from deleted  
  151. Delete MR_Stu_CJ where 学生编号=@id and 学生姓名=@name  
  152. GO  
  153. 注意:在表中删除数据时,将删除的数据存放在系统临时表deleted中。  
  154.   
  155. Update语句创建触发器,当在“MR_Stu_XX”表中更新数据时,“MR_Stu_CJ”表也更新相应的数据。SQL语句如下:  
  156. USE MR_SQL  
  157. GO  
  158. Create TRIGGER TRI_StuXX_Uudate ON [dbo].[MR_Stu_XX]  
  159. FOR Update  
  160. AS  
  161. DECLARE @id char(4),@name char(10)  
  162. select @id=学生编号 from deleted  
  163. select @name=学生姓名 from Inserted  
  164. Update MR_Stu_CJ SET 学生姓名=@name Where 学生编号 = @id  
  165. GO  
  166. 注意:在表中更新数据时,将更新前的数据存放在系统临时表“deleted”中,将更新后的数据存放在系统临时表“inserted”中。  
  167.   
  168. 3.创建触发器的注意事项  
  169.   
  170. (1)触发器是一个数据库对象,它的命名必须符合SQL Server 2000的标识符命名规则。  
  171.   
  172. (2)Create TRIGGER语句必须是批处理中的第一个语句。也就是说,如果该语句前面还有其他语句,应该使用批处理结束符GO隔开。  
  173.   
  174. (3)不能在临时表或系统表上创建触发器,但是在触发器中可以引用临时表,不能引用系统表。  
  175.   
  176. (4)创建触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。  
  177.   
  178. (5)触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。  
  179.   
  180. (6)在含有用 DeleteUpdate操作定义的外键的表中,不能定义INSTEAD OFINSTEAD OF Update触发器。  
  181.   
  182. (7)WRITETEXT 语句不会引发InsertUpdate触发器。  
  183.   
  184. (8)TRUNCATE TABLE语句不能引发Delete触发器,因为该语句没有记录。  

Tags: SQL 触发器

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 73

SQLSEREVER测试题

SQLSEREVER测试题(上)


一 SQLSERVER管理部分


1 请讲出身份验证模式与登录帐号的关系及如何用各种帐号进行登录,并画出示意图
2 请讲出登录帐号、数据库用户及数据库角色之间的关系,并画出示意图
3 请讲出数据库用户、数据库角色与数据库对象之间的关系,并画出直接对用户授权与间接对用户授权(系统权限与对象权限)的方法
4 请讲出服务器角色、数据库角色、标准角色与应用程序角色的区别与验证其权限的方法
5 请讲出数据库还原模型对数据库的影响
6 有一个执行关键任务的数据库,请设计一个数据库备份策略
7 请使用文件与文件组恢复的方式恢复数据库
8 请使用事务日志恢复数据库到一个时间点
9 请设计作业进行周期性的备份数据库
10 如何监控数据库的阻塞,并实现数据库的死锁测试
11 如何监控数据库的活动,并能使用索引优化向导生成索引
12 理解数据库框图的作用并可以设计表与表之间的关系

 

SQL代码
  1. SQLSEREVER测试题(中)  
  2.   
  3. 二 SQLSERVER的实现部分  
  4.   
  5. 1 有订单表,需要实现它的编号,格式如下:200211030001……200222039999等  
  6.   
  7.   
  8.   
  9.   
  10.   
  11. 2 有表T1,T2,现有一事务,在向表T1添加数据时,同时也必须向T2也添加数据,如何实现该事务  
  12.   
  13.   
  14.   
  15.   
  16.   
  17. 3 如何向T1中的编号字段(code varchar(20))添加一万条记录,不充许重复,规则如下:编号的数据必须从小写的a-z之间取值  
  18.   
  19.   
  20.   
  21.   
  22.   
  23. 4 如何删除表中的重复数据,请使用游标与分组的办法  
  24.   
  25.   
  26.   
  27.   
  28.   
  29. 5 如何求表中相邻的两条记录的某字段的值之差  
  30.   
  31.   
  32.   
  33.   
  34.   
  35. 6 如何统计数据库中所有用户表的数据,显示格式如下:  
  36.   
  37. 表名      记录数  
  38.   
  39.   sales      23  
  40.   
  41.   
  42.   
  43.   
  44.   
  45. 7 如何删除数据库中的所有用户表(表与表之间有外键关系)  
  46.   
  47.   
  48.   
  49.   
  50.   
  51. 8 表A editor_id       lb2_id  
  52.    123           000  
  53.    123           003  
  54.    123           003  
  55.    456           007  
  56.    456           006  
  57. 表B  lb2_id         lb2_name  
  58.     000           a  
  59.     003           b  
  60.     006           c  
  61.     007           d  
  62. 显示 a   共1条 (表A内lb2_id为000的条数)  
  63.    b   共2条(表A内lb2_id为003的条数)  
  64.   
  65.   
  66.   
  67.   
  68.   
  69. 9 人员情况表(employee):里面有一字段文化程度(wh):包括四种情况(本科以上,大专,高中,初中以下),现在我要根据年龄字段查询统计出:表中文化程度为本科以上,大专,高中,初中以下,各有多少人,占总人数多少。  
  70.   
  71. Select wh AS 学历,age as 年龄, Count(*) AS 人数,  
  72.   
  73.       Count(*) * 100 /(Select Count(*) FROM employee) AS 百分比  
  74.   
  75. FROM employee GROUP BY wh,age  
  76.   
  77. 学历      年龄    人数      百分比  
  78.   
  79. 本科以上  20      34          14  
  80.   
  81. 大专      20      33          13  
  82.   
  83. 高中      20      33          13  
  84.   
  85. 初中以下  20      100        40  
  86.   
  87. 本科以上  21      50          20  
  88.   
  89.   
  90.   
  91.   
  92.   
  93. 10 现在有三个表student:(FID  学生号,FName  姓名),  
  94.   
  95. subject:(FSubID  课程号,FSubName 课程名),   
  96.   
  97. Score(FScoreId  成绩记录号,FSubID    课程号,FStdID    学生号,FScore    成绩)  
  98.   
  99. 怎么能实现这个表:  
  100.   
  101. 姓名  英语  数学  语文  历史  
  102.   
  103. 张萨  78    67    89    76  
  104.   
  105. 王强  89    67    84    96   
  106.   
  107.   
  108.   
  109.   
  110.   
  111. Select a.FName AS 姓名,  
  112.   
  113.       英语 = SUM(CASE b.FSubName WHEN '英语' THEN c.FScore END),  
  114.   
  115.       数学 = SUM(CASE b.FSubName WHEN '数学' THEN c.FScore END),  
  116.   
  117.       语文 = SUM(CASE b.FSubName WHEN '语文' THEN c.FScore END),  
  118.   
  119.       历史 = SUM(CASE b.FSubName WHEN '历史' THEN c.FScore END)  
  120.   
  121. FROM Student a, Subject b, Score c  
  122.   
  123. Where a.FID = c.FStdId AND b.FSubID = c.FsubID GROUP BY a.FName  
  124.   
  125.   
  126.   
  127.   
  128.   
  129. 11 原始表的数据如下:  
  130.   
  131. PID PTime    PNo  
  132.   
  133. 111111    2003-01-28 04:30:09       
  134.   
  135. 111111    2003-01-28 18:30:00  
  136.   
  137. 222222    2003-01-28 04:31:09       
  138.   
  139. 333333    2003-01-28 04:32:09       
  140.   
  141. 111111    2003-02-09 03:35:25       
  142.   
  143. 222222    2003-02-09 03:36:25       
  144.   
  145. 333333    2003-02-09 03:37:25       
  146.   
  147.   
  148.   
  149.   
  150.   
  151. 查询生成表  
  152.   
  153. PDate        111111        222222    333333      ......  
  154.   
  155. 2003-01-28    04:30:09    04:31:09      04:32:09    ......  
  156.   
  157. 2003-01-28    18:30:00  
  158.   
  159. 2003-02-09    03:35:25    03:36:25      03:37:25    ......  
  160.   
  161.   
  162.   
  163.   
  164.   
  165. 12  表一(AAA)  
  166.   
  167. 商品名称mc  商品总量sl  
  168.   
  169.   A        100  
  170.   
  171.   B        120  
  172.   
  173. 表二(BBB)  
  174.   
  175. 商品名称mc  出库数量sl  
  176.   
  177.   A        10  
  178.   
  179.   A        20  
  180.   
  181.   B        10  
  182.   
  183.   B        20  
  184.   
  185.   B        30  
  186.   
  187.   
  188.   
  189.   
  190.   
  191. 用一条SQL语句算出商品A,B目前还剩多少?  
  192.   
  193. 一  
  194.   
  195.   
  196. declare @AAA table (商品名称  varchar(10), 商品总量  int)  
  197.   
  198. insert into @AAA values('A',100)  
  199.   
  200. insert into @AAA values('B',120)  
  201.   
  202.   
  203.   
  204.   
  205.   
  206. declare @BBB table (商品名称 varchar(10), 出库数量 int)  
  207.   
  208. insert into @BBB values('A', 10)  
  209.   
  210. insert into @BBB values('A', 20)  
  211.   
  212. insert into @BBB values('B', 10)  
  213.   
  214. insert into @BBB values('B', 20)  
  215.   
  216. insert into @BBB values('B', 30)  
  217.   
  218.   
  219.   
  220.   
  221.   
  222. select TA.商品名称,A-B AS 剩余数量 FROM  
  223.   
  224. (select 商品名称,sum(商品总量) AS A  
  225.   
  226. from @AAA  
  227.   
  228. group by 商品名称)TA,  
  229.   
  230. (select 商品名称,sum(出库数量) AS B  
  231.   
  232. from @BBB  
  233.   
  234. group by 商品名称)TB  
  235.   
  236. where TA.商品名称=TB.商品名称  
  237.   
  238. 二  
  239.   
  240.   
  241. select 商品名称,sum(商品总量) 剩余数量 from (select * from @aaa union all select 商品名称,-出库数量 from @bbb) a group by 商品名称  
  242.   
  243.   
  244.   
  245.   
  246.   
  247. 13 优化这句SQL语句  
  248.   
  249. Update tblExlTempYear  
  250.   
  251. SET tblExlTempYear.GDQC = tblExlTempMonth.GDQC  
  252.   
  253. FROM tblExlTempYear,tblExlTempMonth  
  254.   
  255. where tblExlTempMonth.GDXM=tblExlTempYear.GDXM and tblExlTempMonth.TXDZ=tblExlTempYear.TXDZ  
  256.   
  257.   
  258.   
  259.   
  260.   
  261. (1)、加索引:  
  262.   
  263. tblExlTempYear(GDXM,TXDZ)  
  264.   
  265. tblExlTempMonth (GDXM,TXDZ)  
  266.   
  267. (2)、删除无用数据  
  268.   
  269. (3)、转移过时数据  
  270.   
  271. (4)、加服务器内存,升级服务器  
  272.   
  273. (5)、升级网络系统  
  274.   
  275.   
  276.   
  277.   
  278.   
  279. Update tblExlTempYear  
  280.   
  281. SET tblExlTempYear.GDQC = tblExlTempMonth.GDQC  
  282.   
  283. FROM tblExlTempYear (index indexY),tblExlTempMonth (index indexM)  
  284.   
  285. where tblExlTempMonth.GDXM=tblExlTempYear.GDXM and tblExlTempMonth.TXDZ=tblExlTempYear.TXDZ  
  286.   
  287.   
  288.   
  289.   
  290.   
  291. 14 品种    日期    数量  
  292.   
  293. P0001  2002-1-10  10  
  294.   
  295. P0001  2002-1-10  11  
  296.   
  297. P0001  2002-1-10  50  
  298.   
  299. P0001  2002-1-12  9  
  300.   
  301. P0001  2002-1-12  8  
  302.   
  303. P0001  2002-1-12  7  
  304.   
  305. P0002  2002-10-10  5  
  306.   
  307. P0002  2002-10-10  7  
  308.   
  309. P0002  2002-10-12  0.5  
  310.   
  311. P0003  2002-10-10  5  
  312.   
  313. P0003  2002-10-12  7  
  314.   
  315. P0003  2002-10-12  9  
  316.   
  317.   
  318.   
  319.   
  320.   
  321. 结果要先按照品种汇总,再按照日期汇总,结果如下:  
  322.   
  323. P0001  2002-1-10    71  
  324.   
  325. P0001    2002-1-12  24  
  326.   
  327. P0002    2002-10-10  12  
  328.   
  329. P0002    2002-10-12  0.5  
  330.   
  331. P0003    2002-10-10  5  
  332.   
  333. P0003    2002-10-12  16  
  334.   
  335.   
  336.   
  337.   
  338.   
  339. SQL SERVER能做出这样的汇总吗…  
  340.   
  341.   
  342.   
  343.   
  344.   
  345. 15 在分組查循中with{cube|rollup}的區別是什么?  
  346.   
  347. 如:  
  348.   
  349.   use pangu  
  350.   
  351.   select firm_id,p_id,sum(o_price_quantity)as sum_values  
  352.   
  353.   from orders  
  354.   
  355.   group by firm_id,p_id  
  356.   
  357.   with cube  
  358.   
  359.   與  
  360.   
  361.   use pangu  
  362.   
  363.   select firm_id,p_id,sum(o_price_quantity)as sum_values  
  364.   
  365.   from orders  
  366.   
  367.   group by firm_id,p_id  
  368.   
  369.   with rollup  
  370.   
  371.   的區別是什么?  
  372.   
  373.   
  374.   
  375.   
  376.   
  377. CUBE 和 ROLLUP 之间的区别在于:  
  378.   
  379. CUBE 生成的结果集显示了所选列中值的所有组合的聚合。  
  380.   
  381. ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合。  
  382.   
  383. 例如,简单表 Inventory 中包含:  
  384.   
  385. Item                Color                Quantity                   
  386.   
  387. -------------------- -------------------- --------------------------  
  388.   
  389. Table                Blue                124                         
  390.   
  391. Table                Red                  223                         
  392.   
  393. Chair                Blue                101                         
  394.   
  395. Chair                Red                  210                         
  396.   
  397.   
  398.   
  399.   
  400.   
  401.   
  402.   
  403.   
  404.   
  405.   
  406.   
  407.   
  408.   
  409.   
  410. 下列查询将生成小计报表:  
  411.   
  412. Select CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'  
  413.   
  414.             ELSE ISNULL(Item, 'UNKNOWN')  
  415.   
  416.       END AS Item,  
  417.   
  418.       CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'  
  419.   
  420.             ELSE ISNULL(Color, 'UNKNOWN')  
  421.   
  422.       END AS Color,  
  423.   
  424.       SUM(Quantity) AS QtySum  
  425.   
  426. FROM Inventory  
  427.   
  428. GROUP BY Item, Color WITH ROLLUP  
  429.   
  430.   
  431.   
  432.   
  433.   
  434. Item                Color                QtySum                     
  435.   
  436. -------------------- -------------------- --------------------------  
  437.   
  438. Chair                Blue                101.00                     
  439.   
  440. Chair                Red                  210.00                     
  441.   
  442. Chair                ALL                  311.00                     
  443.   
  444. Table                Blue                124.00                     
  445.   
  446. Table                Red                  223.00                     
  447.   
  448. Table                ALL                  347.00                     
  449.   
  450. ALL                  ALL                  658.00                     
  451.   
  452. (7 row(s) affected)  
  453.   
  454. 如果查询中的 ROLLUP 关键字更改为 CUBE,那么 CUBE 结果集与上述结果相同,只是在结果集的末尾还会返回下列两行:  
  455.   
  456. ALL                  Blue                225.00                     
  457.   
  458. ALL                  Red                  433.00                     
  459.   
  460. CUBE 操作为 Item 和 Color 中值的可能组合生成行。例如,CUBE 不仅报告与 Item 值 Chair 相组合的 Color 值的所有可能组合(Red、Blue 和 Red + Blue),而且报告与 Color 值 Red 相组合的 Item 值的所有可能组合(Chair、Table 和 Chair + Table)。对于 GROUP BY 子句中右边的列中的每个值,ROLLUP 操作并不报告左边一列(或左边各列)中值的所有可能组合。例如,ROLLUP 并不对每个 Color 值报告 Item 值的所有可能组合。ROLLUP 操作的结果集具有类似于 COMPUTE BY 所返回结果集的功能;然而,  
  461.   
  462. ROLLUP 具有下列优点: ROLLUP 返回单个结果集;COMPUTE BY 返回多个结果集,而多个结果集会增加应用程序代码的复杂性。ROLLUP 可以在服务器游标中使用;COMPUTE BY 不可以。有时,查询优化器为 ROLLUP 生成的执行计划比为 COMPUTE BY 生成的更为高效。  
  463.   
  464.   
  465.   
  466.   
  467.   
  468. 16 假如我有两个表  
  469. 表1(电话号码,是否存在)  
  470. 表2(电话号码,是否拨打)  
  471. 想查找表1中的电话号码是否在表2中存在,如果存在就更新表1中的是否存在字段为1。  
  472.   
  473.   
  474.   
  475.   
  476.   
  477.     Update 表1 SET 是否存在=1  
  478. Where EXISTS(Select * FROM 表2 Where 表2.电话号码 = 表1.电话号码)  
  479.   
  480.   
  481. 17 用存储过程调用外部程序.  
  482. 不过要做成com控件  
  483. 用sp_OACreate存储过程)  
  484. DECLARE @object int  
  485. DECLARE @hr int  
  486. DECLARE @src varchar(255), @desc varchar(255)  
  487. EXEC @hr = sp_OACreate 'SQLDMO.SQLServer', @object OUT  
  488. IF @hr <> 0  
  489. BEGIN  
  490. EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT  
  491. Select hr=convert(varbinary(4),@hr), Source=@src, Description=@desc  
  492. RETURN  
  493. END   

 

Tags: SQL 免试

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 43

找些不错的sql面试题-2

SQL代码
  1. 问题描述:  
  2. 本题用到下面三个关系表:  
  3. CARD     借书卡。   CNO 卡号,NAME  姓名,CLASS 班级  
  4. BOOKS    图书。     BNO 书号,BNAME 书名,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数   
  5. BORROW   借书记录。 CNO 借书卡号,BNO 书号,RDATE 还书日期  
  6. 备注:限定每人每种书只能借一本;库存册数随借书、还书而改变。  
  7. 要求实现如下15个处理:  
  8.   1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束。  
  9.   2. 找出借书超过5本的读者,输出借书卡号及所借图书册数。  
  10.   3. 查询借阅了"水浒"一书的读者,输出姓名及班级。  
  11.   4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期。  
  12.   5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者。  
  13.   6. 查询现有图书中价格最高的图书,输出书名及作者。  
  14.   7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出。  
  15.   8. 将"C01"班同学所借图书的还期都延长一周。  
  16.   9. 从BOOKS表中删除当前无人借阅的图书记录。  
  17.   10.如果经常按书名查询图书信息,请建立合适的索引。  
  18.   11.在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)。  
  19.   12.建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)。  
  20.   13.查询当前同时借有"计算方法""组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出。  
  21.   14.假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句。  
  22.   15.对CARD表做如下修改:  
  23.     a. 将NAME最大列宽增加到10个字符(假定原为6个字符)。  
  24.     b. 为该表增加1列NAME(系名),可变长,最大20个字符。  
  25.   
  26.   
  27. 1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束  
  28. --实现代码:  
  29. Create TABLE BORROW(  
  30.     CNO int FOREIGN KEY REFERENCES CARD(CNO),  
  31.     BNO int FOREIGN KEY REFERENCES BOOKS(BNO),  
  32.     RDATE datetime,  
  33.     PRIMARY KEY(CNO,BNO))   
  34.   
  35. 2. 找出借书超过5本的读者,输出借书卡号及所借图书册数  
  36. --实现代码:  
  37. Select CNO,借图书册数=COUNT(*)  
  38. FROM BORROW  
  39. GROUP BY CNO  
  40. HAVING COUNT(*)>5  
  41.   
  42. 3. 查询借阅了"水浒"一书的读者,输出姓名及班级  
  43. --实现代码:  
  44. Select * FROM CARD c  
  45. Where EXISTS(  
  46.     Select * FROM BORROW a,BOOKS b   
  47.     Where a.BNO=b.BNO  
  48.         AND b.BNAME=N'水浒'  
  49.         AND a.CNO=c.CNO)   
  50.   
  51. 4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期  
  52. --实现代码:  
  53. Select * FROM BORROW   
  54. Where RDATE<GETDATE()   
  55.   
  56. 5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者  
  57. --实现代码:  
  58. Select BNO,BNAME,AUTHOR FROM BOOKS  
  59. Where BNAME LIKE N'%网络%'   
  60.   
  61. 6. 查询现有图书中价格最高的图书,输出书名及作者  
  62. --实现代码:  
  63. Select BNO,BNAME,AUTHOR FROM BOOKS  
  64. Where PRICE=(  
  65.     Select MAX(PRICE) FROM BOOKS)   
  66.   
  67. 7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出  
  68. --实现代码:  
  69. Select a.CNO  
  70. FROM BORROW a,BOOKS b  
  71. Where a.BNO=b.BNO AND b.BNAME=N'计算方法'  
  72.     AND NOT EXISTS(  
  73.         Select * FROM BORROW aa,BOOKS bb  
  74.         Where aa.BNO=bb.BNO  
  75.             AND bb.BNAME=N'计算方法习题集'  
  76.             AND aa.CNO=a.CNO)  
  77. ORDER BY a.CNO DESC   
  78.   
  79. 8. 将"C01"班同学所借图书的还期都延长一周  
  80. --实现代码:  
  81. Update b SET RDATE=DATEADD(Day,7,b.RDATE)  
  82. FROM CARD a,BORROW b  
  83. Where a.CNO=b.CNO  
  84.     AND a.CLASS=N'C01'   
  85.   
  86. 9. 从BOOKS表中删除当前无人借阅的图书记录  
  87. --实现代码:  
  88. Delete A FROM BOOKS a  
  89. Where NOT EXISTS(  
  90.     Select * FROM BORROW  
  91.     Where BNO=a.BNO)   
  92.   
  93. 10. 如果经常按书名查询图书信息,请建立合适的索引  
  94. --实现代码:  
  95. Create CLUSTERED INDEX IDX_BOOKS_BNAME ON BOOKS(BNAME)  
  96.   
  97. 11. 在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)  
  98. --实现代码:  
  99. Create TRIGGER TR_SAVE ON BORROW  
  100. FOR Insert,Update  
  101. AS  
  102. IF @@ROWCOUNT>0  
  103. Insert BORROW_SAVE Select i.*  
  104. FROM InsertED i,BOOKS b  
  105. Where i.BNO=b.BNO  
  106.     AND b.BNAME=N'数据库技术及应用'   
  107.   
  108. 12. 建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)  
  109. --实现代码:  
  110. Create VIEW V_VIEW  
  111. AS  
  112. Select a.NAME,b.BNAME  
  113. FROM BORROW ab,CARD a,BOOKS b  
  114. Where ab.CNO=a.CNO  
  115.     AND ab.BNO=b.BNO  
  116.     AND a.CLASS=N'力01'  
  117.   
  118. 13. 查询当前同时借有"计算方法""组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出  
  119. --实现代码:  
  120. Select a.CNO  
  121. FROM BORROW a,BOOKS b  
  122. Where a.BNO=b.BNO  
  123.     AND b.BNAME IN(N'计算方法',N'组合数学')  
  124. GROUP BY a.CNO  
  125. HAVING COUNT(*)=2  
  126. ORDER BY a.CNO DESC   
  127.   
  128. 14. 假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句  
  129. --实现代码:  
  130. Alter TABLE BOOKS ADD PRIMARY KEY(BNO)   
  131.   
  132. 15.1 将NAME最大列宽增加到10个字符(假定原为6个字符)  
  133. --实现代码:  
  134. Alter TABLE CARD Alter COLUMN NAME varchar(10)   
  135.   
  136. 15.2 为该表增加1列NAME(系名),可变长,最大20个字符  
  137. --实现代码:  
  138. Alter TABLE CARD ADD 系名 varchar(20)  
  139.   
  140.   
  141.   
  142.   
  143. 问题描述:  
  144. 为管理岗位业务培训信息,建立3个表:  
  145. S (S#,SN,SD,SA)   S#,SN,SD,SA 分别代表学号、学员姓名、所属单位、学员年龄  
  146. C (C#,CN )        C#,CN       分别代表课程编号、课程名称  
  147. SC ( S#,C#,G )    S#,C#,G     分别代表学号、所选修的课程编号、学习成绩  
  148.   
  149. 要求实现如下5个处理:  
  150.   1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名  
  151.   2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位  
  152.   3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位  
  153.   4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位  
  154.   5. 查询选修了课程的学员人数  
  155.   6. 查询选修课程超过5门的学员学号和所属单位  
  156.   
  157. 1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名   
  158. --实现代码:  
  159. Select SN,SD FROM S  
  160. Where [S#] IN(  
  161.     Select [S#] FROM C,SC  
  162.     Where C.[C#]=SC.[C#]  
  163.         AND CN=N'税收基础')  
  164.   
  165.   
  166. 2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位  
  167. --实现代码:  
  168. Select S.SN,S.SD FROM S,SC  
  169. Where S.[S#]=SC.[S#]  
  170.     AND SC.[C#]='C2'  
  171.   
  172. 3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位  
  173. --实现代码:  
  174. Select SN,SD FROM S  
  175. Where [S#] NOT IN(  
  176.     Select [S#] FROM SC   
  177.     Where [C#]='C5')  
  178.   
  179. 4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位  
  180. --实现代码:  
  181. Select SN,SD FROM S  
  182. Where [S#] IN(  
  183.     Select [S#] FROM SC   
  184.         RIGHT JOIN C ON SC.[C#]=C.[C#]  
  185.     GROUP BY [S#]  
  186.     HAVING COUNT(*)=COUNT(DISTINCT [S#]))  
  187.   
  188. 5. 查询选修了课程的学员人数  
  189. --实现代码:  
  190. Select 学员人数=COUNT(DISTINCT [S#]) FROM SC  
  191.   
  192. 6. 查询选修课程超过5门的学员学号和所属单位  
  193. --实现代码:  
  194. Select SN,SD FROM S  
  195. Where [S#] IN(  
  196.     Select [S#] FROM SC   
  197.     GROUP BY [S#]  
  198.     HAVING COUNT(DISTINCT [C#])>5)  

Tags: SQL 收集

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 34

找些不错的sql面试题-1

SQL代码
  1. Student(S#,Sname,Sage,Ssex) 学生表   
  2. Course(C#,Cname,T#) 课程表   
  3. SC(S#,C#,score) 成绩表   
  4. Teacher(T#,Tname) 教师表   
  5.   
  6. 问题:   
  7. 1、查询“001”课程比“002”课程成绩高的所有学生的学号;   
  8.   select a.S# from (select s#,score from SC where C#='001') a,(select s#,score   
  9.   from SC where C#='002') b   
  10.   where a.score>b.score and a.s#=b.s#;   
  11. 2、查询平均成绩大于60分的同学的学号和平均成绩;   
  12.     select S#,avg(score)   
  13.     from sc   
  14.     group by S# having avg(score) >60;   
  15. 3、查询所有同学的学号、姓名、选课数、总成绩;   
  16.   select Student.S#,Student.Sname,count(SC.C#),sum(score)   
  17.   from Student left Outer join SC on Student.S#=SC.S#   
  18.   group by Student.S#,Sname   
  19. 4、查询姓“李”的老师的个数;   
  20.   select count(distinct(Tname))   
  21.   from Teacher   
  22.   where Tname like '李%';   
  23. 5、查询没学过“叶平”老师课的同学的学号、姓名;   
  24.     select Student.S#,Student.Sname   
  25.     from Student    
  26.     where S# not in (select distinct( SC.S#) from SC,Course,Teacher where  SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='叶平');   
  27. 6、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;   
  28.   select Student.S#,Student.Sname from Student,SC where Student.S#=SC.S# and SC.C#='001'and exists( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#='002');   
  29. 7、查询学过“叶平”老师所教的所有课的同学的学号、姓名;   
  30.   select S#,Sname   
  31.   from Student   
  32.   where S# in (select S# from SC ,Course ,Teacher where SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='叶平' group by S# having count(SC.C#)=(select count(C#) from Course,Teacher  where Teacher.T#=Course.T# and Tname='叶平'));   
  33. 8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;   
  34.   Select S#,Sname from (select Student.S#,Student.Sname,score ,(select score from SC SC_2 where SC_2.S#=Student.S# and SC_2.C#='002') score2   
  35.   from Student,SC where Student.S#=SC.S# and C#='001') S_2 where score2 <score;   
  36. 9、查询所有课程成绩小于60分的同学的学号、姓名;   
  37.   select S#,Sname   
  38.   from Student   
  39.   where S# not in (select Student.S# from Student,SC where S.S#=SC.S# and score>60);   
  40. 10、查询没有学全所有课的同学的学号、姓名;   
  41.     select Student.S#,Student.Sname   
  42.     from Student,SC   
  43.     where Student.S#=SC.S# group by  Student.S#,Student.Sname having count(C#) <(select count(C#) from Course);   
  44. 11、查询至少有一门课与学号为“1001”的同学所学相同的同学的学号和姓名;   
  45.     select S#,Sname from Student,SC where Student.S#=SC.S# and C# in select C# from SC where S#='1001';   
  46. 12、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;   
  47.     select distinct SC.S#,Sname   
  48.     from Student,SC   
  49.     where Student.S#=SC.S# and C# in (select C# from SC where S#='001');   
  50. 13、把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;   
  51.     update SC set score=(select avg(SC_2.score)   
  52.     from SC SC_2   
  53.     where SC_2.C#=SC.C# ) from Course,Teacher where Course.C#=SC.C# and Course.T#=Teacher.T# and Teacher.Tname='叶平');   
  54. 14、查询和“1002”号的同学学习的课程完全相同的其他同学学号和姓名;   
  55.     select S# from SC where C# in (select C# from SC where S#='1002')   
  56.     group by S# having count(*)=(select count(*) from SC where S#='1002');   
  57. 15、删除学习“叶平”老师课的SC表记录;   
  58.     Delect SC   
  59.     from course ,Teacher    
  60.     where Course.C#=SC.C# and Course.T#= Teacher.T# and Tname='叶平';   
  61. 16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号“003”课程的同学学号、2、   
  62.     号课的平均成绩;   
  63.     Insert SC select S#,'002',(Select avg(score)   
  64.     from SC where C#='002'from Student where S# not in (Select S# from SC where C#='002');   
  65. 17、按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示: 学生ID,,数据库,企业管理,英语,有效课程数,有效平均分   
  66.     Select S# as 学生ID   
  67.         ,(Select score FROM SC Where SC.S#=t.S# AND C#='004'AS 数据库   
  68.         ,(Select score FROM SC Where SC.S#=t.S# AND C#='001'AS 企业管理   
  69.         ,(Select score FROM SC Where SC.S#=t.S# AND C#='006'AS 英语   
  70.         ,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩   
  71.     FROM SC AS t   
  72.     GROUP BY S#   
  73.     ORDER BY avg(t.score)    
  74. 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分   
  75.     Select L.C# As 课程ID,L.score AS 最高分,R.score AS 最低分   
  76.     FROM SC L ,SC AS R   
  77.     Where L.C# = R.C# and   
  78.         L.score = (Select MAX(IL.score)   
  79.                       FROM SC AS IL,Student AS IM   
  80.                       Where L.C# = IL.C# and IM.S#=IL.S#   
  81.                       GROUP BY IL.C#)   
  82.         AND   
  83.         R.Score = (Select MIN(IR.score)   
  84.                       FROM SC AS IR   
  85.                       Where R.C# = IR.C#   
  86.                   GROUP BY IR.C#   
  87.                     );   
  88. 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序   
  89.     Select t.C# AS 课程号,max(course.Cname)AS 课程名,isnull(AVG(score),0) AS 平均成绩   
  90.         ,100 * SUM(CASE WHEN  isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数   
  91.     FROM SC T,Course   
  92.     where t.C#=course.C#   
  93.     GROUP BY t.C#   
  94.     ORDER BY 100 * SUM(CASE WHEN  isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC   
  95. 20、查询如下课程平均成绩和及格率的百分数(用"1行"显示): 企业管理(001),马克思(002),OO&UML (003),数据库(004)   
  96.     Select SUM(CASE WHEN C# ='001' THEN score ELSE 0 END)/SUM(CASE C# WHEN '001' THEN 1 ELSE 0 ENDAS 企业管理平均分   
  97.         ,100 * SUM(CASE WHEN C# = '001' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '001' THEN 1 ELSE 0 ENDAS 企业管理及格百分数   
  98.         ,SUM(CASE WHEN C# = '002' THEN score ELSE 0 END)/SUM(CASE C# WHEN '002' THEN 1 ELSE 0 ENDAS 马克思平均分   
  99.         ,100 * SUM(CASE WHEN C# = '002' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '002' THEN 1 ELSE 0 ENDAS 马克思及格百分数   
  100.         ,SUM(CASE WHEN C# = '003' THEN score ELSE 0 END)/SUM(CASE C# WHEN '003' THEN 1 ELSE 0 ENDAS UML平均分   
  101.         ,100 * SUM(CASE WHEN C# = '003' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '003' THEN 1 ELSE 0 ENDAS UML及格百分数   
  102.         ,SUM(CASE WHEN C# = '004' THEN score ELSE 0 END)/SUM(CASE C# WHEN '004' THEN 1 ELSE 0 ENDAS 数据库平均分   
  103.         ,100 * SUM(CASE WHEN C# = '004' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '004' THEN 1 ELSE 0 ENDAS 数据库及格百分数   
  104.   FROM SC  
  105.   
  106.   
  107. 21、查询不同老师所教不同课程平均分从高到低显示   
  108.   Select max(Z.T#) AS 教师ID,MAX(Z.Tname) AS 教师姓名,C.C# AS 课程ID,MAX(C.Cname) AS 课程名称,AVG(Score) AS 平均成绩   
  109.     FROM SC AS T,Course AS C ,Teacher AS Z   
  110.     where T.C#=C.C# and C.T#=Z.T#   
  111.   GROUP BY C.C#   
  112.   ORDER BY AVG(Score) DESC   
  113. 22、查询如下课程成绩第 3 名到第 6 名的学生成绩单:企业管理(001),马克思(002),UML (003),数据库(004)   
  114.     [学生ID],[学生姓名],企业管理,马克思,UML,数据库,平均成绩   
  115.     Select  DISTINCT top 3   
  116.       SC.S# As 学生学号,   
  117.         Student.Sname AS 学生姓名 ,   
  118.       T1.score AS 企业管理,   
  119.       T2.score AS 马克思,   
  120.       T3.score AS UML,   
  121.       T4.score AS 数据库,   
  122.       ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) as 总分   
  123.       FROM Student,SC  LEFT JOIN SC AS T1   
  124.                       ON SC.S# = T1.S# AND T1.C# = '001'   
  125.             LEFT JOIN SC AS T2   
  126.                       ON SC.S# = T2.S# AND T2.C# = '002'   
  127.             LEFT JOIN SC AS T3   
  128.                       ON SC.S# = T3.S# AND T3.C# = '003'   
  129.             LEFT JOIN SC AS T4   
  130.                       ON SC.S# = T4.S# AND T4.C# = '004'   
  131.       Where student.S#=SC.S# and   
  132.       ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)   
  133.       NOT IN   
  134.       (Select   
  135.             DISTINCT   
  136.             TOP 15 WITH TIES   
  137.             ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)   
  138.       FROM sc   
  139.             LEFT JOIN sc AS T1   
  140.                       ON sc.S# = T1.S# AND T1.C# = 'k1'   
  141.             LEFT JOIN sc AS T2   
  142.                       ON sc.S# = T2.S# AND T2.C# = 'k2'   
  143.             LEFT JOIN sc AS T3   
  144.                       ON sc.S# = T3.S# AND T3.C# = 'k3'   
  145.             LEFT JOIN sc AS T4   
  146.                       ON sc.S# = T4.S# AND T4.C# = 'k4'   
  147.       ORDER BY ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) DESC);   
  148.   
  149. 23、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]   
  150.     Select SC.C# as 课程ID, Cname as 课程名称   
  151.         ,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 ENDAS [100 - 85]   
  152.         ,SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 ENDAS [85 - 70]   
  153.         ,SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 ENDAS [70 - 60]   
  154.         ,SUM(CASE WHEN score < 60 THEN 1 ELSE 0 ENDAS [60 -]   
  155.     FROM SC,Course   
  156.     where SC.C#=Course.C#   
  157.     GROUP BY SC.C#,Cname;   
  158.   
  159. 24、查询学生平均成绩及其名次   
  160.       Select 1+(Select COUNTdistinct 平均成绩)   
  161.               FROM (Select S#,AVG(score) AS 平均成绩   
  162.                       FROM SC   
  163.                   GROUP BY S#   
  164.                   ) AS T1   
  165.             Where 平均成绩 > T2.平均成绩) as 名次,   
  166.       S# as 学生学号,平均成绩   
  167.     FROM (Select S#,AVG(score) 平均成绩   
  168.             FROM SC   
  169.         GROUP BY S#   
  170.         ) AS T2   
  171.     ORDER BY 平均成绩 desc;   
  172.     
  173. 25、查询各科成绩前三名的记录:(不考虑成绩并列情况)   
  174.       Select t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数   
  175.       FROM SC t1   
  176.       Where score IN (Select TOP 3 score   
  177.               FROM SC   
  178.               Where t1.C#= C#   
  179.             ORDER BY score DESC   
  180.               )   
  181.       ORDER BY t1.C#;   
  182. 26、查询每门课程被选修的学生数   
  183.   select c#,count(S#) from sc group by C#;   
  184. 27、查询出只选修了一门课程的全部学生的学号和姓名   
  185.   select SC.S#,Student.Sname,count(C#) AS 选课数   
  186.   from SC ,Student   
  187.   where SC.S#=Student.S# group by SC.S# ,Student.Sname having count(C#)=1;   
  188. 28、查询男生、女生人数   
  189.     Select count(Ssex) as 男生人数 from Student group by Ssex having Ssex='男';   
  190.     Select count(Ssex) as 女生人数 from Student group by Ssex having Ssex='女';   
  191. 29、查询姓“张”的学生名单   
  192.     Select Sname FROM Student Where Sname like '张%';   
  193. 30、查询同名同性学生名单,并统计同名人数   
  194.   select Sname,count(*) from Student group by Sname having  count(*)>1;;   
  195. 31、1981年出生的学生名单(注:Student表中Sage列的类型是datetime)   
  196.     select Sname,  CONVERT(char (11),DATEPART(year,Sage)) as age   
  197.     from student   
  198.     where  CONVERT(char(11),DATEPART(year,Sage))='1981';   
  199. 32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列   
  200.     Select C#,Avg(score) from SC group by C# order by Avg(score),C# DESC ;   
  201. 33、查询平均成绩大于85的所有学生的学号、姓名和平均成绩   
  202.     select Sname,SC.S# ,avg(score)   
  203.     from Student,SC   
  204.     where Student.S#=SC.S# group by SC.S#,Sname having    avg(score)>85;   
  205. 34、查询课程名称为“数据库”,且分数低于60的学生姓名和分数   
  206.     Select Sname,isnull(score,0)   
  207.     from Student,SC,Course   
  208.     where SC.S#=Student.S# and SC.C#=Course.C# and  Course.Cname='数据库'and score <60;   
  209. 35、查询所有学生的选课情况;   
  210.     Select SC.S#,SC.C#,Sname,Cname   
  211.     FROM SC,Student,Course   
  212.     where SC.S#=Student.S# and SC.C#=Course.C# ;   
  213. 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;   
  214.     Select  distinct student.S#,student.Sname,SC.C#,SC.score   
  215.     FROM student,Sc   
  216.     Where SC.score>=70 AND SC.S#=student.S#;   
  217. 37、查询不及格的课程,并按课程号从大到小排列   
  218.     select c# from sc where scor e <60 order by C# ;   
  219. 38、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;   
  220.     select SC.S#,Student.Sname from SC,Student where SC.S#=Student.S# and Score>80 and C#='003';   
  221. 39、求选了课程的学生人数   
  222.     select count(*) from sc;   
  223. 40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩   
  224.     select Student.Sname,score   
  225.     from Student,SC,Course C,Teacher   
  226.     where Student.S#=SC.S# and SC.C#=C.C# and C.T#=Teacher.T# and Teacher.Tname='叶平' and SC.score=(select max(score)from SC where C#=C.C# );   
  227. 41、查询各个课程及相应的选修人数   
  228.     select count(*) from sc group by C#;   
  229. 42、查询不同课程成绩相同的学生的学号、课程号、学生成绩   
  230.   select distinct  A.S#,B.score from SC A  ,SC B where A.Score=B.Score and A.C# <>B.C# ;   
  231. 43、查询每门功成绩最好的前两名   
  232.     Select t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数   
  233.       FROM SC t1   
  234.       Where score IN (Select TOP 2 score   
  235.               FROM SC   
  236.               Where t1.C#= C#   
  237.             ORDER BY score DESC   
  238.               )   
  239.       ORDER BY t1.C#;   
  240. 44、统计每门课程的学生选修人数(超过10人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,查询结果按人数降序排列,若人数相同,按课程号升序排列    
  241.     select  C# as 课程号,count(*) as 人数   
  242.     from  sc    
  243.     group  by  C#   
  244.     order  by  count(*) desc,c#    
  245. 45、检索至少选修两门课程的学生学号   
  246.     select  S#    
  247.     from  sc    
  248.     group  by  s#   
  249.     having  count(*)  >  =  2   
  250. 46、查询全部学生都选修的课程的课程号和课程名   
  251.     select  C#,Cname    
  252.     from  Course    
  253.     where  C#  in  (select  c#  from  sc group  by  c#)    
  254. 47、查询没学过“叶平”老师讲授的任一门课程的学生姓名   
  255.     select Sname from Student where S# not in (select S# from Course,Teacher,SC where Course.T#=Teacher.T# and SC.C#=course.C# and Tname='叶平');   
  256. 48、查询两门以上不及格课程的同学的学号及其平均成绩   
  257.     select S#,avg(isnull(score,0)) from SC where S# in (select S# from SC where score <60 group by S# having count(*)>2)group by S#;   
  258. 49、检索“004”课程分数小于60,按分数降序排列的同学学号   
  259.     select S# from SC where C#='004'and score <60 order by score desc;   
  260. 50、删除“002”同学的“001”课程的成绩   
  261. delete from Sc where S#='001'and C#='001';  

Tags: SQL 面试

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 46

整理精华帖子

行列转换:
http://topic.csdn.net/u/20080614/17/22e73f33-f071-46dc-b9bf-321204b1656f.html?33238(总 结帖子)
http://topic.csdn.net/u/20090912/14/25d2e1b2-f352-4713-8618-d3433ba27bef.html?99104(经 典帖子)

合并分拆表:
http://topic.csdn.net/u/20080612/22/c850499f-bce3-4877-82d5-af2357857872.html?23514
果果字符串整理系列

处理表重复记录
http://topic.csdn.net/u/20080626/00/43d0d10c-28f1-418d-a05b-663880da278a.html?85256

SSAS系列:
过渡到SSAS之一:简单模型认识
过渡到SSAS之二:服务的发布
和尚翻译的SSRS的帖子

SSIS系列:

小梁系列之SSIS遍历记录查询邮件

小梁系列之SSIS表达式

小梁系列之SSIS “查找组件” 查找范围内的数据

小梁系列之SSIS 同步和异步转换

小梁系列之SSIS中 “条件拆分”组件中 ISNUMERIC的问题

小梁系列之脚本任务中访问记录集 RecordSet

小梁系列之SSIS中数据源和数据目标中 的”保留空值”


有关SQL注入的帖子:
SQL注入专题
http://topic.csdn.net/u/20090326/11/5e584897-2dd7-4e10-af1b-9b48b146af8e.html?95281
http://topic.csdn.net/u/20090523/19/72041932-b65c-49c1-ad36-d2c63b38b174.html?96607

经典代码系列:
经典短小代码
第一季
第二季
最近的一个
http://topic.csdn.net/u/20080605/15/ca6b25f3-3e60-4b95-ac7e-7d7dc02354e6.html?87229
T-SQL常见基础疑点问答整理(1)
T-SQL常见基础疑点问答整理(2)


石头系列之2005事务与锁定系列
事务与锁定第一篇
事务与锁定第二篇
事务与锁定第三篇
事务与锁定第四篇
事务与锁定第五篇
事务与锁定第六篇

石头系列之数据库引擎结构
数据库引擎结构一
数据库引擎结构二
数据库引擎结构三

各种进制的转换:(来自影子)
http://topic.csdn.net/u/20090707/16/9a7b8e46-1467-4373-a195-39d80b826827.html?28501

关于数据库的同步的帖子:
http://topic.csdn.net/u/20080523/11/08e4624a-13d1-4a6c-a9bc-7cfdd721a351.html?4574
http://topic.csdn.net/u/20080801/11/2f79d062-8049-4ade-a884-01dbaa429135.html?63426
http://topic.csdn.net/u/20090520/22/2267467b-0c40-4a5e-8b71-24838be0ff64.html?10943
两台服务器的相互同步


数据的导入导出部分:
CSV文件批量导入数据库
http://topic.csdn.net/u/20091009/11/5f3ebd1a-de5f-4d92-bc76-0f2103a34b5a.html?48287
excel导入SQL
http://topic.csdn.net/u/20090724/00/a479a979-8a20-4abb-a184-8a0ee56608c2.html?86864
BCP:
http://topic.csdn.net/u/20090720/21/b27734aa-c091-4a6b-96db-f234e2699385.html?84209
http://topic.csdn.net/u/20090720/21/b27734aa-c091-4a6b-96db-f234e2699385.html?2600
数据的转移
一个比较巧的导法

数据的分页:
http://topic.csdn.net/u/20090416/02/4e3cb6d6-707a-4f42-b295-3e9fd5df7691.html?52379

SQL查询与性能优化系列:
SQL性能优化综述
SQL Server查询优化
SQL优化之执行计划
五种提高SQL性能的方法
SQL开发的二十一条军规
一千万条数据的优化
如何提高sql查询100万条数据 count(*)汇总的速度
数据库优化汇总
海量数据库的相关处理

索引系列:
全文索引
查看索引信息/生成创建索引脚本
聚焦索引与非聚焦索引及其查询效率

递归函数系列:
BOM:
其他:
http://topic.csdn.net/u/20090807/08/19f980a3-3830-4261-90ca-0f85ec628492.html?62247

如何判断一个IP地址在一个IP地址段

身份证号码的转化

2005CLR系列:

环比运算
树结构
天气服务
正则表达式

数据库的并发性以及锁相关的帖子:
一个简单的存储过程产生死锁
单条Update语句是否加事务与锁的关系
分析死锁并整理


触发器、存储过程等
触发器综述

触发器删除的一个问题

分组求前N条数据:
分组求前N条数据

数据库的备份与恢复等问题
数据库的备份与恢复等问题
还原指定文件夹下的备份

作业:
自动备份数据库作业

SQL常见的安装问题
SQL常见的安装问题
SQL不能连接的完美解决方案

远程连接操作 整理帖子
远程连接操作 整理帖子

自动生成流水号
自动生成流水号

求每行的最小的那个字母

数据库的加密
数据库的加密

根据时间求某个月所有日期或者某天的所有时间段
根据时间求某个月所有日期或者某天的所有时间段

如何查漏号字段
如何查漏号字段

多列求最大值或者最小值
多列求最大值或者最小值

Tags: SQL 收集

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 40
SQL代码
  1. 1:replace 函数  
  2. 第一个参数你的字符串,第二个参数你想替换的部分,第三个参数你要替换成什么  
  3. select replace('lihan','a','b')  
  4.                                                                     
  5. -----------------------------  
  6. lihbn  
  7.   
  8. (所影响的行数为 1 行)  
  9. =========================================================  
  10. 2:substring函数  
  11. 第一个参数你的字符串,第二个是开始替换位置,第三个结束替换位置  
  12. select substring('lihan',0,3);  
  13. -----   
  14. li  
  15.   
  16. (所影响的行数为 1 行)  
  17. =========================================================  
  18. 3:charindex函数  
  19. 第一个参数你要查找的char,第二个参数你被查找的字符串 返回参数一在参数二的位置  
  20. select  charindex('a','lihan')  
  21. -----------   
  22. 4  
  23.   
  24. (所影响的行数为 1 行)  
  25.   
  26. ===========================================================  
  27. 4:ASCII函数  
  28. 返回字符表达式中最左侧的字符的 ASCII 代码值。  
  29. select ASCII('lihan')  
  30. -----------   
  31. 108  
  32.   
  33. (所影响的行数为 1 行)  
  34.   
  35. ================================================================  
  36. 5:nchar函数  
  37. 根据 Unicode 标准的定义,返回具有指定的整数代码的 Unicode 字符。  
  38. 参数是介于 0 与 65535 之间的正整数。如果指定了超出此范围的值,将返回 NULL。  
  39. select nchar(3213)  
  40. ----   
  41. unicode字符  
  42.   
  43. (所影响的行数为 1 行)  
  44.   
  45. =========================================================  
  46. 6:soundex  
  47. 返回一个由四个字符组成的代码 (SOUNDEX),用于评估两个字符串的相似性。  
  48. Select SOUNDEX ('lihan'), SOUNDEX ('lihon');  
  49. ----- -----   
  50. L546  L542  
  51.   
  52. (所影响的行数为 1 行)  
  53. =========================================================  
  54. 7:char  
  55. 参数为介于 0 和 255 之间的整数。如果该整数表达式不在此范围内,将返回 NULL 值。  
  56. Select char(125)  
  57. ----   
  58. }  
  59.   
  60. (所影响的行数为 1 行)  
  61.   
  62. ==========================================================  
  63. 8:str函数  
  64. 第一个参数必须为数字,第二个参数表示转化成char型占的位置,小于参数一位置返回*,大于右对齐  
  65. Select str(12345,3)  
  66. ----   
  67. ***  
  68.   
  69. (所影响的行数为 1 行)  
  70.   
  71. Select str(12345,12)  
  72. ------------   
  73.        12345  
  74.   
  75. (所影响的行数为 1 行)  
  76. ===========================================================  
  77. 9:difference函数  
  78. 返回一个整数值,指示两个字符表达式的 SOUNDEX 值之间的差异。  
  79. 返回的整数是 SOUNDEX 值中相同字符的个数。返回的值从 0 到 4 不等:0 表示几乎不同或完全不同,4 表示几乎相同或完全相同。  
  80. Select difference('lihan','liha')  
  81. -----------   
  82. 3  
  83.   
  84. (所影响的行数为 1 行)  
  85.   
  86.   
  87. ==================================================================  
  88. 10:stuff函数(四个参数)  
  89. 函数将字符串插入另一字符串。它在第一个字符串中从开始位置删除指定长度的字符;然后将第二个字符串插入第一个字符串的开始位置。  
  90. Select stuff('lihan',2,3,'lihan')  
  91. --------   
  92. llihann  
  93.   
  94. (所影响的行数为 1 行)  
  95. ===============================================================  
  96.   
  97. 11:left函数  
  98. 返回最左边N个字符,由参数决定  
  99. select left('lihan',4)  
  100. -----   
  101. liha  
  102.   
  103. (所影响的行数为 1 行)  
  104. ================================================================  
  105.   
  106. 12 right函数  
  107. 返回最右边N个字符,由参数决定  
  108. select right('lihan',4)  
  109. -----   
  110. ihan  
  111.   
  112. (所影响的行数为 1 行)  
  113. ================================================================  
  114.   
  115. 13:replicate函数  
  116. 我的认为是把参数一复制参数二次  
  117. select replicate('lihan',4)  
  118. --------------------   
  119. lihanlihanlihanlihan  
  120.   
  121. (所影响的行数为 1 行)  
  122.   
  123. ================================================================  
  124.   
  125. 14:len函数  
  126. 返回参数长度  
  127. select len('lihan')  
  128. -----------   
  129. 5  
  130.   
  131. (所影响的行数为 1 行)  
  132.   
  133.   
  134. ================================================================  
  135. 15:reverse函数  
  136. 反转字符串  
  137. select reverse('lihan')  
  138. -----   
  139. nahil  
  140.   
  141. (所影响的行数为 1 行)  
  142.   
  143.   
  144. =================================================================  
  145.   
  146. 16:lowerupper函数  
  147. 参数大小写转化  
  148. select lower(upper('lihan'))  
  149. --------------------   
  150. lihan  
  151.   
  152. (所影响的行数为 1 行)  
  153.   
  154. ====================================================================  
  155.   
  156. 17:ltrim和rtrim函数  
  157. 删除左边空格和右面空格  
  158. select ltrim('    lihan                 ')  
  159. --------------------------   
  160. lihan                   
  161.   
  162. (所影响的行数为 1 行)  
  163. select rtrim('    lihan')  
  164. ---------   
  165.     lihan  
  166.   
  167. (所影响的行数为 1 行)  

Tags: SQL 收集

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 69

如果你正在负责一个基于SQL Server的项目,或者你刚刚接触SQL Server,你都有可能要面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于其它的DBMS)。
在这里,我 不打算介绍使用SQL Server的窍门,也不能提供一个包治百病的方案,我所做的是总结一些经验----关于如何形成一个好的设计。这些经验来自我过去几年中经受的教训,一 直来,我看到许多同样的设计错误被一次又一次的重复。
一、了解你用的工具
不要轻视这一点,这是我在这篇文章中讲述的最关键的一条。也许你 也看到有很多的SQL Server程序员没有掌握全部的T-SQL命令和SQL Server提供的那些有用的工具。
“什么?我要浪费一个月的 时间来学习那些我永远也不会用到的SQL命令???”,你也许会这样说。对的,你不需要这样做。但是你应该用一个周末浏览所有的T-SQL命令。在这里, 你的任务是了解,将来,当你设计一个查询时,你会记起来:“对了,这里有一个命令可以完全实现我需要的功能”,于是,到MSDN查看这个命令的确切语法。
二、 不要使用游标
让我再重复一遍:不要使用游标。如果你想破坏整个系统的性能的话,它们倒是你最有效的首选办法。大多数的初学者都使用游标,而没有意 识到它们对性能造成的影响。它们占用内存,还用它们那些不可思议的方式锁定表,另外,它们简直就像蜗牛。而最糟糕的是,它们可以使你的DBA所能做的一切 性能优化等于没做。不知你是否知道每执行一次FETCH就等于执行一次Select命令?这意味着如果你的游标有10000条记录,它将执行10000次 Select!如果你使用一组Select、Update或者Delete来完成相应的工作,那将有效率的多。
初学者一般认为使用游标是一种比较 熟悉和舒适的编程方式,可很不幸,这会导致糟糕的性能。显然,SQL的总体目的是你要实现什么,而不是怎样实现。
我曾经用T-SQL重写了一个基 于游标的存储过程,那个表只有100,000条记录,原来的存储过程用了40分钟才执行完毕,而新的存储过程只用了10秒钟。在这里,我想你应该可以看到 一个不称职的程序员究竟在干了什么!!!
我们可以写一个小程序来取得和处理数据并且更新数据库,这样做有时会更有效。记住:对于循环,T-SQL 无能为力。
我再重新提醒一下:使用游标没有好处。除了DBA的工作外,我从来没有看到过使用游标可以有效的完成任何工作。
三、规范化你的 数据表
为什么不规范化数据库?大概有两个借口:出于性能的考虑和纯粹因为懒惰。至于第二点,你迟早得为此付出代价。而关于性能的问题,你不需要优 化根本就不慢的东西。我经常看到一些程序员“反规范化”数据库,他们的理由是“原来的设计太慢了”,可结果却常常是他们让系统更慢了。DBMS被设计用来 处理规范数据库的,因此,记住:按照规范化的要求设计数据库。
四、不要使用Select *
这点不太容易做到,我太了解了,因为我自己 就经常这样干。可是,如果在Select中指定你所需要的列,那将会带来以下的好处:
1 减少内存耗费和网络的带宽
2 你可以得到更安全的设计
3 给查询优化器机会从索引读取所有需要的列
五、了解你将要对数据进行的操作
为你的数据库创建一个健壮的 索引,那可是功德一件。可要做到这一点简直就是一门艺术。每当你为一个表添加一个索引,Select会更快了,可Insert和Delete却大大的变慢 了,因为创建了维护索引需要许多额外的工作。显然,这里问题的关键是:你要对这张表进行什么样的操作。这个问题不太好把握,特别是涉及Delete和 Update时,因为这些语句经常在Where部分包含Select命令。
六、不要给“性别”列创建索引
首先,我们必须了解索引是如何加 速对表的访问的。你可以将索引理解为基于一定的标准上对表进行划分的一种方式。如果你给类似于“性别”这样的列创建了一个索引,你仅仅是将表划分为两部 分:男和女。你在处理一个有1,000,000条记录的表,这样的划分有什么意义?记住:维护索引是比较费时的。当你设计索引时,请遵循这样的规则:根据 列可能包含不同内容的数目从多到少排列,比如:姓名+省份+性别。
七、使用事务
请使用事务,特别是当查询比较耗时。如果系统出现问题,这 样做会救你一命的。一般有些经验的程序员都有体会-----你经常会碰到一些不可预料的情况会导致存储过程崩溃。
八、小心死锁
按照一定的 次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再 锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁是不太容易被发现的。
九、不要打开大的数据集
一个经常被提 出的问题是:我怎样才能迅速的将100000条记录添加到ComboBox中?这是不对的,你不能也不需要这样做。很简单,你的用户要浏览100000条 记录才能找到需要的记录,他一定会诅咒你的。在这里,你需要的是一个更好的UI,你需要为你的用户显示不超过100或200条记录。
十、不要使用 服务器端游标
与服务器端游标比起来,客户端游标可以减少服务器和网络的系统开销,并且还减少锁定时间。
十一、使用参数查询
有时, 我在CSDN技术论坛看到类似这样的问题:“Select * FROM a Where a.id='A'B,因为单引号查询发生异常,我该怎么办?”,而普遍的回答是:用两个单引号代替单引号。这是错误的。这样治标不治本,因为你还会在其他 一些字符上遇到这样的问题,更何况这样会导致严重的bug,除此以外,这样做还会使SQL Server的缓冲系统无法发挥应有的作用。使用参数查询, 釜底抽薪,这些问题统统不存在了。
十二、在程序编码时使用大数据量的数据库
程序员在开发中使用的测试数据库一般数据量都不大,可经常的是 最终用户的数据量都很大。我们通常的做法是不对的,原因很简单:现在硬盘不是很贵,可为什么性能问题却要等到已经无可挽回的时候才被注意呢?
十 三、不要使用Insert导入大批的数据
请不要这样做,除非那是必须的。使用UTS或者BCP,这样你可以一举而兼得灵活性和速度。
十 四、注意超时问题
查询数据库时,一般数据库的缺省都比较小,比如15秒或者30秒。而有些查询运行时间要比这长,特别是当数据库的数据量不断变大 时。
十五、不要忽略同时修改同一记录的问题
有时候,两个用户会同时修改同一记录,这样,后一个修改者修改了前一个修改者的操作,某些更新 就会丢失。处理这种情况不是很难:创建一个timestamp字段,在写入前检查它,如果允许,就合并修改,如果存在冲突,提示用户。
十六、在细 节表中插入纪录时,不要在主表执行Select MAX(ID)
这是一个普遍的错误,当两个用户在同一时间插入数据时,这会导致错误。你可以使用 SCOPE_IDENTITY,IDENT_CURRENT和IDENTITY。如果可能,不要使用IDENTITY,因为在有触发器的情况下,它会引起 一些问题(详见这里的讨论)。
十七、避免将列设为NULLable
如果可能的话,你应该避免将列设为NULLable。系统会为 NULLable列的每一行分配一个额外的字节,查询时会带来更多的系统开销。另外,将列设为NULLable使编码变得复杂,因为每一次访问这些列时都 必须先进行检查。
我并不是说NULLS是麻烦的根源,尽管有些人这样认为。我认为如果你的业务规则中允许“空数据”,那么,将列设为 NULLable有时会发挥很好的作用,但是,如果在类似下面的情况中使用NULLable,那简直就是自讨苦吃。
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
如 果出现这种情况,你需要规范化你的表了。
十八、尽量不要使用TEXT数据类型
除非你使用TEXT处理一个很大的数据,否则不要使用它。因 为它不易于查询,速度慢,用的不好还会浪费大量的空间。一般的,VARCHAR可以更好的处理你的数据。
十九、尽量不要使用临时表
尽量不 要使用临时表,除非你必须这样做。一般使用子查询可以代替临时表。使用临时表会带来系统开销,如果你是用COM+进行编程,它还会给你带来很大的麻烦,因 为COM+使用数据库连接池而临时表却自始至终都存在。SQL Server提供了一些替代方案,比如Table数据类型。
二十、学会分析查询
SQL Server查询分析器是你的好伙伴,通过它你可以了解查询和索引是如何影响性能的。
二十一、使用参照完整性
定义主健、唯一性约束和外 键,这样做可以节约大量的时间。

Tags: SQL 军规

分类:MSSQL | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 45